mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-07-03 17:58:30 +00:00
Initial import
This commit is contained in:
commit
c91b3c5006
14915 changed files with 590219 additions and 0 deletions
58
third_party/zlib/LICENSE
vendored
Normal file
58
third_party/zlib/LICENSE
vendored
Normal file
|
@ -0,0 +1,58 @@
|
|||
zlib
|
||||
version 1.2.11, January 15th, 2017
|
||||
|
||||
Copyright (C) 1995-2017 Jean-loup Gailly and Mark Adler
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
Jean-loup Gailly Mark Adler
|
||||
jloup@gzip.org madler@alumni.caltech.edu
|
||||
|
||||
The data format used by the zlib library is described by RFCs (Request for
|
||||
Comments) 1950 to 1952 in the files http://tools.ietf.org/html/rfc1950
|
||||
(zlib format), rfc1951 (deflate format) and rfc1952 (gzip format).
|
||||
|
||||
────────────────────────────────────────────────────────────────────────────────
|
||||
chromium/third_party/zlib
|
||||
|
||||
Copyright 2015 The Chromium Authors. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following disclaimer
|
||||
in the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
* Neither the name of Google Inc. nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
3
third_party/zlib/README.cosmo
vendored
Normal file
3
third_party/zlib/README.cosmo
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
Sourced from Chromium due to overextended influence by maintainers whose
|
||||
important contributions in this field should be recognized by clarifying
|
||||
claims of ownership for posterity. See also libc/str/undeflate.c
|
161
third_party/zlib/adler32.c
vendored
Normal file
161
third_party/zlib/adler32.c
vendored
Normal file
|
@ -0,0 +1,161 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=4 sts=4 sw=4 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 1995-2016 Mark Adler │
|
||||
│ Copyright 2017 The Chromium Authors │
|
||||
│ Use of this source code is governed by the BSD-style licenses that can │
|
||||
│ be found in the third_party/zlib/LICENSE file. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/dce.h"
|
||||
#include "libc/nexgen32e/x86feature.h"
|
||||
#include "third_party/zlib/internal.h"
|
||||
#include "third_party/zlib/zutil.h"
|
||||
|
||||
asm(".ident\t\"\\n\\n\
|
||||
zlib (zlib License)\\n\
|
||||
Copyright 1995-2017 Jean-loup Gailly and Mark Adler\"");
|
||||
asm(".include \"libc/disclaimer.inc\"");
|
||||
|
||||
#define BASE 65521U /* largest prime smaller than 65536 */
|
||||
#define NMAX 5552 /* largest n such that 255n(n+1)/2+(n+1)(BASE-1)<=2^32-1 */
|
||||
|
||||
#define DO1(buf, i) \
|
||||
{ \
|
||||
adler += (buf)[i]; \
|
||||
sum2 += adler; \
|
||||
}
|
||||
#define DO2(buf, i) \
|
||||
DO1(buf, i); \
|
||||
DO1(buf, i + 1);
|
||||
#define DO4(buf, i) \
|
||||
DO2(buf, i); \
|
||||
DO2(buf, i + 2);
|
||||
#define DO8(buf, i) \
|
||||
DO4(buf, i); \
|
||||
DO4(buf, i + 4);
|
||||
#define DO16(buf) \
|
||||
DO8(buf, 0); \
|
||||
DO8(buf, 8);
|
||||
|
||||
/* use NO_DIVIDE if your processor does not do division in hardware --
|
||||
try it both ways to see which is faster */
|
||||
#ifdef NO_DIVIDE
|
||||
/* note that this assumes BASE is 65521, where 65536 % 65521 == 15
|
||||
(thank you to John Reiser for pointing this out) */
|
||||
#define CHOP(a) \
|
||||
do { \
|
||||
unsigned long tmp = a >> 16; \
|
||||
a &= 0xffffUL; \
|
||||
a += (tmp << 4) - tmp; \
|
||||
} while (0)
|
||||
#define MOD28(a) \
|
||||
do { \
|
||||
CHOP(a); \
|
||||
if (a >= BASE) a -= BASE; \
|
||||
} while (0)
|
||||
#define MOD(a) \
|
||||
do { \
|
||||
CHOP(a); \
|
||||
MOD28(a); \
|
||||
} while (0)
|
||||
#define MOD63(a) \
|
||||
do { /* this assumes a is not negative */ \
|
||||
int64_t tmp = a >> 32; \
|
||||
a &= 0xffffffffL; \
|
||||
a += (tmp << 8) - (tmp << 5) + tmp; \
|
||||
tmp = a >> 16; \
|
||||
a &= 0xffffL; \
|
||||
a += (tmp << 4) - tmp; \
|
||||
tmp = a >> 16; \
|
||||
a &= 0xffffL; \
|
||||
a += (tmp << 4) - tmp; \
|
||||
if (a >= BASE) a -= BASE; \
|
||||
} while (0)
|
||||
#else
|
||||
#define MOD(a) a %= BASE
|
||||
#define MOD28(a) a %= BASE
|
||||
#define MOD63(a) a %= BASE
|
||||
#endif
|
||||
|
||||
uLong adler32_z(uLong adler, const Bytef *buf, size_t len) {
|
||||
return adler32(adler, buf, len);
|
||||
}
|
||||
|
||||
uLong adler32(uLong adler, const Bytef *buf, uInt len) {
|
||||
unsigned long sum2;
|
||||
unsigned n;
|
||||
if (!IsTiny() && X86_HAVE(SSSE3) && buf && len >= 64) {
|
||||
return adler32_simd_(adler, buf, len);
|
||||
}
|
||||
/* split Adler-32 into component sums */
|
||||
sum2 = (adler >> 16) & 0xffff;
|
||||
adler &= 0xffff;
|
||||
/* in case user likes doing a byte at a time, keep it fast */
|
||||
if (len == 1) {
|
||||
adler += buf[0];
|
||||
if (adler >= BASE) adler -= BASE;
|
||||
sum2 += adler;
|
||||
if (sum2 >= BASE) sum2 -= BASE;
|
||||
return adler | (sum2 << 16);
|
||||
}
|
||||
/* initial Adler-32 value (deferred check for len == 1 speed) */
|
||||
if (buf == Z_NULL) return 1L;
|
||||
/* in case short lengths are provided, keep it somewhat fast */
|
||||
if (len < 16) {
|
||||
while (len--) {
|
||||
adler += *buf++;
|
||||
sum2 += adler;
|
||||
}
|
||||
if (adler >= BASE) adler -= BASE;
|
||||
MOD28(sum2); /* only added so many BASE's */
|
||||
return adler | (sum2 << 16);
|
||||
}
|
||||
/* do length NMAX blocks -- requires just one modulo operation */
|
||||
while (len >= NMAX) {
|
||||
len -= NMAX;
|
||||
n = NMAX / 16; /* NMAX is divisible by 16 */
|
||||
do {
|
||||
DO16(buf); /* 16 sums unrolled */
|
||||
buf += 16;
|
||||
} while (--n);
|
||||
MOD(adler);
|
||||
MOD(sum2);
|
||||
}
|
||||
/* do remaining bytes (less than NMAX, still just one modulo) */
|
||||
if (len) { /* avoid modulos if none remaining */
|
||||
while (len >= 16) {
|
||||
len -= 16;
|
||||
DO16(buf);
|
||||
buf += 16;
|
||||
}
|
||||
while (len--) {
|
||||
adler += *buf++;
|
||||
sum2 += adler;
|
||||
}
|
||||
MOD(adler);
|
||||
MOD(sum2);
|
||||
}
|
||||
/* return recombined sums */
|
||||
return adler | (sum2 << 16);
|
||||
}
|
||||
|
||||
uLong adler32_combine(uLong adler1, uLong adler2, int64_t len2) {
|
||||
unsigned long sum1;
|
||||
unsigned long sum2;
|
||||
unsigned rem;
|
||||
/* for negative len, return invalid adler32 as a clue for debugging */
|
||||
if (len2 < 0) return 0xffffffffUL;
|
||||
/* the derivation of this formula is left as an exercise for the reader */
|
||||
MOD63(len2); /* assumes len2 >= 0 */
|
||||
rem = (unsigned)len2;
|
||||
sum1 = adler1 & 0xffff;
|
||||
sum2 = rem * sum1;
|
||||
MOD(sum2);
|
||||
sum1 += (adler2 & 0xffff) + BASE - 1;
|
||||
sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem;
|
||||
if (sum1 >= BASE) sum1 -= BASE;
|
||||
if (sum1 >= BASE) sum1 -= BASE;
|
||||
if (sum2 >= ((unsigned long)BASE << 1)) sum2 -= ((unsigned long)BASE << 1);
|
||||
if (sum2 >= BASE) sum2 -= BASE;
|
||||
return sum1 | (sum2 << 16);
|
||||
}
|
194
third_party/zlib/adler32simd.c
vendored
Normal file
194
third_party/zlib/adler32simd.c
vendored
Normal file
|
@ -0,0 +1,194 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=4 sts=4 sw=4 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2017 The Chromium Authors │
|
||||
│ Use of this source code is governed by the BSD-style licenses that can │
|
||||
│ be found in the third_party/zlib/LICENSE file. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/bits/emmintrin.h"
|
||||
#include "libc/bits/tmmintrin.h"
|
||||
#include "third_party/zlib/internal.h"
|
||||
|
||||
asm(".ident\t\"\\n\\n\
|
||||
Chromium (BSD-3 License)\\n\
|
||||
Copyright 2017 The Chromium Authors\"");
|
||||
asm(".include \"libc/disclaimer.inc\"");
|
||||
|
||||
/**
|
||||
* Per http://en.wikipedia.org/wiki/Adler-32 the adler32 A value (aka s1) is
|
||||
* the sum of N input data bytes D1 ... DN,
|
||||
*
|
||||
* A = A0 + D1 + D2 + ... + DN
|
||||
*
|
||||
* where A0 is the initial value.
|
||||
*
|
||||
* SSE2 _mm_sad_epu8() can be used for byte sums (see http://bit.ly/2wpUOeD,
|
||||
* for example) and accumulating the byte sums can use SSE shuffle-adds (see
|
||||
* the "Integer" section of http://bit.ly/2erPT8t for details). Arm NEON has
|
||||
* similar instructions.
|
||||
*
|
||||
* The adler32 B value (aka s2) sums the A values from each step:
|
||||
*
|
||||
* B0 + (A0 + D1) + (A0 + D1 + D2) + ... + (A0 + D1 + D2 + ... + DN) or
|
||||
*
|
||||
* B0 + N.A0 + N.D1 + (N-1).D2 + (N-2).D3 + ... + (N-(N-1)).DN
|
||||
*
|
||||
* B0 being the initial value. For 32 bytes (ideal for garden-variety SIMD):
|
||||
*
|
||||
* B = B0 + 32.A0 + [D1 D2 D3 ... D32] x [32 31 30 ... 1].
|
||||
*
|
||||
* Adjacent blocks of 32 input bytes can be iterated with the expressions to
|
||||
* compute the adler32 s1 s2 of M >> 32 input bytes [1].
|
||||
*
|
||||
* As M grows, the s1 s2 sums grow. If left unchecked, they would eventually
|
||||
* overflow the precision of their integer representation (bad). However, s1
|
||||
* and s2 also need to be computed modulo the adler BASE value (reduced). If
|
||||
* at most NMAX bytes are processed before a reduce, s1 s2 _cannot_ overflow
|
||||
* a uint32_t type (the NMAX constraint) [2].
|
||||
*
|
||||
* [1] the iterative equations for s2 contain constant factors; these can be
|
||||
* hoisted from the n-blocks do loop of the SIMD code.
|
||||
*
|
||||
* [2] zlib adler32_z() uses this fact to implement NMAX-block-based updates
|
||||
* of the adler s1 s2 of uint32_t type (see adler32.c).
|
||||
*/
|
||||
|
||||
/* Definitions from adler32.c: largest prime smaller than 65536 */
|
||||
#define BASE 65521U
|
||||
/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
|
||||
#define NMAX 5552
|
||||
|
||||
uint32_t adler32_simd_(uint32_t adler, const unsigned char *buf, size_t len) {
|
||||
/*
|
||||
* Split Adler-32 into component sums.
|
||||
*/
|
||||
uint32_t s1 = adler & 0xffff;
|
||||
uint32_t s2 = adler >> 16;
|
||||
|
||||
/*
|
||||
* Process the data in blocks.
|
||||
*/
|
||||
const unsigned BLOCK_SIZE = 1 << 5;
|
||||
|
||||
size_t blocks = len / BLOCK_SIZE;
|
||||
len -= blocks * BLOCK_SIZE;
|
||||
|
||||
while (blocks) {
|
||||
unsigned n = NMAX / BLOCK_SIZE; /* The NMAX constraint. */
|
||||
if (n > blocks) n = (unsigned)blocks;
|
||||
blocks -= n;
|
||||
|
||||
const __m128i tap1 = _mm_setr_epi8(32, 31, 30, 29, 28, 27, 26, 25, 24, 23,
|
||||
22, 21, 20, 19, 18, 17);
|
||||
const __m128i tap2 =
|
||||
_mm_setr_epi8(16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1);
|
||||
const __m128i zero =
|
||||
_mm_setr_epi8(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||
const __m128i ones = _mm_set_epi16(1, 1, 1, 1, 1, 1, 1, 1);
|
||||
|
||||
/*
|
||||
* Process n blocks of data. At most NMAX data bytes can be
|
||||
* processed before s2 must be reduced modulo BASE.
|
||||
*/
|
||||
__m128i v_ps = _mm_set_epi32(0, 0, 0, s1 * n);
|
||||
__m128i v_s2 = _mm_set_epi32(0, 0, 0, s2);
|
||||
__m128i v_s1 = _mm_set_epi32(0, 0, 0, 0);
|
||||
|
||||
do {
|
||||
/*
|
||||
* Load 32 input bytes.
|
||||
*/
|
||||
const __m128i bytes1 = _mm_loadu_si128((__m128i *)(buf));
|
||||
const __m128i bytes2 = _mm_loadu_si128((__m128i *)(buf + 16));
|
||||
|
||||
/*
|
||||
* Add previous block byte sum to v_ps.
|
||||
*/
|
||||
v_ps = _mm_add_epi32(v_ps, v_s1);
|
||||
|
||||
/*
|
||||
* Horizontally add the bytes for s1, multiply-adds the
|
||||
* bytes by [ 32, 31, 30, ... ] for s2.
|
||||
*/
|
||||
v_s1 = _mm_add_epi32(v_s1, _mm_sad_epu8(bytes1, zero));
|
||||
const __m128i mad1 = _mm_maddubs_epi16(bytes1, tap1);
|
||||
v_s2 = _mm_add_epi32(v_s2, _mm_madd_epi16(mad1, ones));
|
||||
|
||||
v_s1 = _mm_add_epi32(v_s1, _mm_sad_epu8(bytes2, zero));
|
||||
const __m128i mad2 = _mm_maddubs_epi16(bytes2, tap2);
|
||||
v_s2 = _mm_add_epi32(v_s2, _mm_madd_epi16(mad2, ones));
|
||||
|
||||
buf += BLOCK_SIZE;
|
||||
|
||||
} while (--n);
|
||||
|
||||
v_s2 = _mm_add_epi32(v_s2, _mm_slli_epi32(v_ps, 5));
|
||||
|
||||
/*
|
||||
* Sum epi32 ints v_s1(s2) and accumulate in s1(s2).
|
||||
*/
|
||||
|
||||
#define S23O1 _MM_SHUFFLE(2, 3, 0, 1) /* A B C D -> B A D C */
|
||||
#define S1O32 _MM_SHUFFLE(1, 0, 3, 2) /* A B C D -> C D A B */
|
||||
|
||||
v_s1 = _mm_add_epi32(v_s1, _mm_shuffle_epi32(v_s1, S23O1));
|
||||
v_s1 = _mm_add_epi32(v_s1, _mm_shuffle_epi32(v_s1, S1O32));
|
||||
|
||||
s1 += _mm_cvtsi128_si32(v_s1);
|
||||
|
||||
v_s2 = _mm_add_epi32(v_s2, _mm_shuffle_epi32(v_s2, S23O1));
|
||||
v_s2 = _mm_add_epi32(v_s2, _mm_shuffle_epi32(v_s2, S1O32));
|
||||
|
||||
s2 = _mm_cvtsi128_si32(v_s2);
|
||||
|
||||
#undef S23O1
|
||||
#undef S1O32
|
||||
|
||||
/*
|
||||
* Reduce.
|
||||
*/
|
||||
s1 %= BASE;
|
||||
s2 %= BASE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle leftover data.
|
||||
*/
|
||||
if (len) {
|
||||
if (len >= 16) {
|
||||
s2 += (s1 += *buf++);
|
||||
s2 += (s1 += *buf++);
|
||||
s2 += (s1 += *buf++);
|
||||
s2 += (s1 += *buf++);
|
||||
|
||||
s2 += (s1 += *buf++);
|
||||
s2 += (s1 += *buf++);
|
||||
s2 += (s1 += *buf++);
|
||||
s2 += (s1 += *buf++);
|
||||
|
||||
s2 += (s1 += *buf++);
|
||||
s2 += (s1 += *buf++);
|
||||
s2 += (s1 += *buf++);
|
||||
s2 += (s1 += *buf++);
|
||||
|
||||
s2 += (s1 += *buf++);
|
||||
s2 += (s1 += *buf++);
|
||||
s2 += (s1 += *buf++);
|
||||
s2 += (s1 += *buf++);
|
||||
|
||||
len -= 16;
|
||||
}
|
||||
|
||||
while (len--) {
|
||||
s2 += (s1 += *buf++);
|
||||
}
|
||||
|
||||
if (s1 >= BASE) s1 -= BASE;
|
||||
s2 %= BASE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the recombined sums.
|
||||
*/
|
||||
return s1 | (s2 << 16);
|
||||
}
|
344
third_party/zlib/chunkcopy.h
vendored
Normal file
344
third_party/zlib/chunkcopy.h
vendored
Normal file
|
@ -0,0 +1,344 @@
|
|||
#ifndef THIRD_PARTY_ZLIB_CHUNKCOPY_H
|
||||
#define THIRD_PARTY_ZLIB_CHUNKCOPY_H
|
||||
#include "libc/bits/emmintrin.h"
|
||||
#include "third_party/zlib/zutil.h"
|
||||
|
||||
asm(".ident\t\"\\n\\n\
|
||||
Chromium (BSD-3 License)\\n\
|
||||
Copyright 2017 The Chromium Authors\"");
|
||||
asm(".include \"libc/disclaimer.inc\"");
|
||||
|
||||
/**
|
||||
* @fileoverview fast chunk copy and set operations
|
||||
*
|
||||
* The chunk-copy code above deals with writing the decoded DEFLATE data
|
||||
* to the output with SIMD methods to increase decode speed. Reading the
|
||||
* input to the DEFLATE decoder with a wide, SIMD method can also
|
||||
* increase decode speed. This option is supported on little endian
|
||||
* machines, and reads the input data in 64-bit (8 byte) chunks.
|
||||
*/
|
||||
|
||||
#define Z_BUILTIN_MEMCPY __builtin_memcpy
|
||||
#define Z_RESTRICT restrict
|
||||
#define Z_STATIC_ASSERT(name, assert) typedef char name[(assert) ? 1 : -1]
|
||||
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
|
||||
typedef long long z_vec128i_t _Vector_size(16);
|
||||
|
||||
/*
|
||||
* chunk copy type: the z_vec128i_t type size should be exactly 128-bits
|
||||
* and equal to CHUNKCOPY_CHUNK_SIZE.
|
||||
*/
|
||||
#define CHUNKCOPY_CHUNK_SIZE sizeof(z_vec128i_t)
|
||||
|
||||
Z_STATIC_ASSERT(vector_128_bits_wide,
|
||||
CHUNKCOPY_CHUNK_SIZE == sizeof(int8_t) * 16);
|
||||
|
||||
/**
|
||||
* Ask the compiler to perform a wide, unaligned load with a machine
|
||||
* instruction appropriate for the z_vec128i_t type.
|
||||
*/
|
||||
static inline z_vec128i_t loadchunk(const unsigned char *s) {
|
||||
z_vec128i_t v;
|
||||
Z_BUILTIN_MEMCPY(&v, s, sizeof(v));
|
||||
return v;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ask the compiler to perform a wide, unaligned store with a machine
|
||||
* instruction appropriate for the z_vec128i_t type.
|
||||
*/
|
||||
static inline void storechunk(unsigned char *d, const z_vec128i_t v) {
|
||||
Z_BUILTIN_MEMCPY(d, &v, sizeof(v));
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform a memcpy-like operation, assuming that length is non-zero and
|
||||
* that it's OK to overwrite at least CHUNKCOPY_CHUNK_SIZE bytes of
|
||||
* output even if the length is shorter than this.
|
||||
*
|
||||
* It also guarantees that it will properly unroll the data if the distance
|
||||
* between `out` and `from` is at least CHUNKCOPY_CHUNK_SIZE, which we rely on
|
||||
* in chunkcopy_relaxed().
|
||||
*
|
||||
* Aside from better memory bus utilisation, this means that short copies
|
||||
* (CHUNKCOPY_CHUNK_SIZE bytes or fewer) will fall straight through the loop
|
||||
* without iteration, which will hopefully make the branch prediction more
|
||||
* reliable.
|
||||
*/
|
||||
static inline unsigned char *chunkcopy_core(unsigned char *out,
|
||||
const unsigned char *from,
|
||||
unsigned len) {
|
||||
const int bump = (--len % CHUNKCOPY_CHUNK_SIZE) + 1;
|
||||
storechunk(out, loadchunk(from));
|
||||
out += bump;
|
||||
from += bump;
|
||||
len /= CHUNKCOPY_CHUNK_SIZE;
|
||||
while (len-- > 0) {
|
||||
storechunk(out, loadchunk(from));
|
||||
out += CHUNKCOPY_CHUNK_SIZE;
|
||||
from += CHUNKCOPY_CHUNK_SIZE;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Like chunkcopy_core(), but avoid writing beyond of legal output.
|
||||
*
|
||||
* Accepts an additional pointer to the end of safe output. A generic safe
|
||||
* copy would use (out + len), but it's normally the case that the end of the
|
||||
* output buffer is beyond the end of the current copy, and this can still be
|
||||
* exploited.
|
||||
*/
|
||||
static inline unsigned char *chunkcopy_core_safe(unsigned char *out,
|
||||
const unsigned char *from,
|
||||
unsigned len,
|
||||
unsigned char *limit) {
|
||||
Assert(out + len <= limit, "chunk copy exceeds safety limit");
|
||||
if ((limit - out) < (ptrdiff_t)CHUNKCOPY_CHUNK_SIZE) {
|
||||
const unsigned char *Z_RESTRICT rfrom = from;
|
||||
if (len & 8) {
|
||||
Z_BUILTIN_MEMCPY(out, rfrom, 8);
|
||||
out += 8;
|
||||
rfrom += 8;
|
||||
}
|
||||
if (len & 4) {
|
||||
Z_BUILTIN_MEMCPY(out, rfrom, 4);
|
||||
out += 4;
|
||||
rfrom += 4;
|
||||
}
|
||||
if (len & 2) {
|
||||
Z_BUILTIN_MEMCPY(out, rfrom, 2);
|
||||
out += 2;
|
||||
rfrom += 2;
|
||||
}
|
||||
if (len & 1) {
|
||||
*out++ = *rfrom++;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
return chunkcopy_core(out, from, len);
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform short copies until distance can be rewritten as being at
|
||||
* least CHUNKCOPY_CHUNK_SIZE.
|
||||
*
|
||||
* Assumes it's OK to overwrite at least the first 2*CHUNKCOPY_CHUNK_SIZE
|
||||
* bytes of output even if the copy is shorter than this. This assumption
|
||||
* holds within zlib inflate_fast(), which starts every iteration with at
|
||||
* least 258 bytes of output space available (258 being the maximum length
|
||||
* output from a single token; see inffast.c).
|
||||
*/
|
||||
static inline unsigned char *chunkunroll_relaxed(unsigned char *out,
|
||||
unsigned *dist,
|
||||
unsigned *len) {
|
||||
const unsigned char *from = out - *dist;
|
||||
while (*dist < *len && *dist < CHUNKCOPY_CHUNK_SIZE) {
|
||||
storechunk(out, loadchunk(from));
|
||||
out += *dist;
|
||||
*len -= *dist;
|
||||
*dist += *dist;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
/**
|
||||
* v_load64_dup(): load *src as an unaligned 64-bit int and duplicate it
|
||||
* in every 64-bit component of the 128-bit result (64-bit int splat).
|
||||
*/
|
||||
static inline z_vec128i_t v_load64_dup(const void *src) {
|
||||
int64_t i64;
|
||||
Z_BUILTIN_MEMCPY(&i64, src, sizeof(i64));
|
||||
return _mm_set1_epi64x(i64);
|
||||
}
|
||||
|
||||
/**
|
||||
* v_load32_dup(): load *src as an unaligned 32-bit int and duplicate it
|
||||
* in every 32-bit component of the 128-bit result (32-bit int splat).
|
||||
*/
|
||||
static inline z_vec128i_t v_load32_dup(const void *src) {
|
||||
int32_t i32;
|
||||
Z_BUILTIN_MEMCPY(&i32, src, sizeof(i32));
|
||||
return _mm_set1_epi32(i32);
|
||||
}
|
||||
|
||||
/**
|
||||
* v_load16_dup(): load *src as an unaligned 16-bit int and duplicate it
|
||||
* in every 16-bit component of the 128-bit result (16-bit int splat).
|
||||
*/
|
||||
static inline z_vec128i_t v_load16_dup(const void *src) {
|
||||
int16_t i16;
|
||||
Z_BUILTIN_MEMCPY(&i16, src, sizeof(i16));
|
||||
return _mm_set1_epi16(i16);
|
||||
}
|
||||
|
||||
/**
|
||||
* v_load8_dup(): load the 8-bit int *src and duplicate it in every
|
||||
* 8-bit component of the 128-bit result (8-bit int splat).
|
||||
*/
|
||||
static inline z_vec128i_t v_load8_dup(const void *src) {
|
||||
return _mm_set1_epi8(*(const char *)src);
|
||||
}
|
||||
|
||||
/**
|
||||
* v_store_128(): store the 128-bit vec in a memory destination (that
|
||||
* might not be 16-byte aligned) void* out.
|
||||
*/
|
||||
static inline void v_store_128(void *out, const z_vec128i_t vec) {
|
||||
_mm_storeu_si128((__m128i *)out, vec);
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform an overlapping copy which behaves as a memset() operation,
|
||||
* but supporting periods other than one, and assume that length is
|
||||
* non-zero and that it's OK to overwrite at least
|
||||
* CHUNKCOPY_CHUNK_SIZE*3 bytes of output even if the length is shorter
|
||||
* than this.
|
||||
*/
|
||||
static inline unsigned char *chunkset_core(unsigned char *out, unsigned period,
|
||||
unsigned len) {
|
||||
z_vec128i_t v;
|
||||
const int bump = ((len - 1) % sizeof(v)) + 1;
|
||||
switch (period) {
|
||||
case 1:
|
||||
v = v_load8_dup(out - 1);
|
||||
v_store_128(out, v);
|
||||
out += bump;
|
||||
len -= bump;
|
||||
while (len > 0) {
|
||||
v_store_128(out, v);
|
||||
out += sizeof(v);
|
||||
len -= sizeof(v);
|
||||
}
|
||||
return out;
|
||||
case 2:
|
||||
v = v_load16_dup(out - 2);
|
||||
v_store_128(out, v);
|
||||
out += bump;
|
||||
len -= bump;
|
||||
if (len > 0) {
|
||||
v = v_load16_dup(out - 2);
|
||||
do {
|
||||
v_store_128(out, v);
|
||||
out += sizeof(v);
|
||||
len -= sizeof(v);
|
||||
} while (len > 0);
|
||||
}
|
||||
return out;
|
||||
case 4:
|
||||
v = v_load32_dup(out - 4);
|
||||
v_store_128(out, v);
|
||||
out += bump;
|
||||
len -= bump;
|
||||
if (len > 0) {
|
||||
v = v_load32_dup(out - 4);
|
||||
do {
|
||||
v_store_128(out, v);
|
||||
out += sizeof(v);
|
||||
len -= sizeof(v);
|
||||
} while (len > 0);
|
||||
}
|
||||
return out;
|
||||
case 8:
|
||||
v = v_load64_dup(out - 8);
|
||||
v_store_128(out, v);
|
||||
out += bump;
|
||||
len -= bump;
|
||||
if (len > 0) {
|
||||
v = v_load64_dup(out - 8);
|
||||
do {
|
||||
v_store_128(out, v);
|
||||
out += sizeof(v);
|
||||
len -= sizeof(v);
|
||||
} while (len > 0);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
out = chunkunroll_relaxed(out, &period, &len);
|
||||
return chunkcopy_core(out, out - period, len);
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform a memcpy-like operation, but assume that length is non-zero
|
||||
* and that it's OK to overwrite at least CHUNKCOPY_CHUNK_SIZE bytes of
|
||||
* output even if the length is shorter than this.
|
||||
*
|
||||
* Unlike chunkcopy_core() above, no guarantee is made regarding the behaviour
|
||||
* of overlapping buffers, regardless of the distance between the pointers.
|
||||
* This is reflected in the `restrict`-qualified pointers, allowing the
|
||||
* compiler to re-order loads and stores.
|
||||
*/
|
||||
static inline unsigned char *chunkcopy_relaxed(
|
||||
unsigned char *Z_RESTRICT out, const unsigned char *Z_RESTRICT from,
|
||||
unsigned len) {
|
||||
return chunkcopy_core(out, from, len);
|
||||
}
|
||||
|
||||
/**
|
||||
* Like chunkcopy_relaxed(), but avoid writing beyond of legal output.
|
||||
*
|
||||
* Unlike chunkcopy_core_safe() above, no guarantee is made regarding the
|
||||
* behaviour of overlapping buffers, regardless of the distance between the
|
||||
* pointers. This is reflected in the `restrict`-qualified pointers, allowing
|
||||
* the compiler to re-order loads and stores.
|
||||
*
|
||||
* Accepts an additional pointer to the end of safe output. A generic safe
|
||||
* copy would use (out + len), but it's normally the case that the end of the
|
||||
* output buffer is beyond the end of the current copy, and this can still be
|
||||
* exploited.
|
||||
*/
|
||||
static inline unsigned char *chunkcopy_safe(
|
||||
unsigned char *out, const unsigned char *Z_RESTRICT from, unsigned len,
|
||||
unsigned char *limit) {
|
||||
Assert(out + len <= limit, "chunk copy exceeds safety limit");
|
||||
return chunkcopy_core_safe(out, from, len, limit);
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform chunky copy within the same buffer, where the source and
|
||||
* destination may potentially overlap.
|
||||
*
|
||||
* Assumes that len > 0 on entry, and that it's safe to write at least
|
||||
* CHUNKCOPY_CHUNK_SIZE*3 bytes to the output.
|
||||
*/
|
||||
static inline unsigned char *chunkcopy_lapped_relaxed(unsigned char *out,
|
||||
unsigned dist,
|
||||
unsigned len) {
|
||||
if (dist < len && dist < CHUNKCOPY_CHUNK_SIZE) {
|
||||
return chunkset_core(out, dist, len);
|
||||
}
|
||||
return chunkcopy_core(out, out - dist, len);
|
||||
}
|
||||
|
||||
/**
|
||||
* Behave like chunkcopy_lapped_relaxed(), but avoid writing beyond of
|
||||
* legal output.
|
||||
*
|
||||
* Accepts an additional pointer to the end of safe output. A generic safe
|
||||
* copy would use (out + len), but it's normally the case that the end of the
|
||||
* output buffer is beyond the end of the current copy, and this can still be
|
||||
* exploited.
|
||||
*/
|
||||
static inline unsigned char *chunkcopy_lapped_safe(unsigned char *out,
|
||||
unsigned dist, unsigned len,
|
||||
unsigned char *limit) {
|
||||
Assert(out + len <= limit, "chunk copy exceeds safety limit");
|
||||
if ((limit - out) < (ptrdiff_t)(3 * CHUNKCOPY_CHUNK_SIZE)) {
|
||||
/* TODO(cavalcantii): try harder to optimise this */
|
||||
while (len-- > 0) {
|
||||
*out = *(out - dist);
|
||||
out++;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
return chunkcopy_lapped_relaxed(out, dist, len);
|
||||
}
|
||||
|
||||
#undef Z_STATIC_ASSERT
|
||||
#undef Z_RESTRICT
|
||||
#undef Z_BUILTIN_MEMCPY
|
||||
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* THIRD_PARTY_ZLIB_CHUNKCOPY_H */
|
88
third_party/zlib/compress.c
vendored
Normal file
88
third_party/zlib/compress.c
vendored
Normal file
|
@ -0,0 +1,88 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=4 sts=4 sw=4 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 1995-2005, 2014, 2016 Jean-loup Gailly, Mark Adler │
|
||||
│ Use of this source code is governed by the BSD-style licenses that can │
|
||||
│ be found in the third_party/zlib/LICENSE file. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "third_party/zlib/zlib.h"
|
||||
|
||||
asm(".ident\t\"\\n\\n\
|
||||
zlib (zlib License)\\n\
|
||||
Copyright 1995-2017 Jean-loup Gailly and Mark Adler\"");
|
||||
asm(".include \"libc/disclaimer.inc\"");
|
||||
|
||||
int compress(Bytef *dest, uLongf *destLen, const Bytef *source,
|
||||
uLong sourceLen) {
|
||||
return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compresses the source buffer into the destination buffer. The level
|
||||
* parameter has the same meaning as in deflateInit. sourceLen is the
|
||||
* byte length of the source buffer. Upon entry, destLen is the total
|
||||
* size of the destination buffer, which must be at least 0.1% larger
|
||||
* than sourceLen plus 12 bytes. Upon exit, destLen is the actual size
|
||||
* of the compressed buffer.
|
||||
*
|
||||
* @return Z_OK if success, Z_MEM_ERROR if there was not enough memory,
|
||||
* Z_BUF_ERROR if there was not enough room in the output buffer,
|
||||
* Z_STREAM_ERROR if the level parameter is invalid.
|
||||
*/
|
||||
int compress2(Bytef *dest, uLongf *destLen, const Bytef *source,
|
||||
uLong sourceLen, int level) {
|
||||
z_stream stream;
|
||||
int err;
|
||||
const uInt max = (uInt)-1;
|
||||
uLong left;
|
||||
|
||||
left = *destLen;
|
||||
*destLen = 0;
|
||||
|
||||
stream.zalloc = (alloc_func)0;
|
||||
stream.zfree = (free_func)0;
|
||||
stream.opaque = (voidpf)0;
|
||||
|
||||
err = deflateInit(&stream, level);
|
||||
if (err != Z_OK) return err;
|
||||
|
||||
stream.next_out = dest;
|
||||
stream.avail_out = 0;
|
||||
stream.next_in = (const Bytef *)source;
|
||||
stream.avail_in = 0;
|
||||
|
||||
do {
|
||||
if (stream.avail_out == 0) {
|
||||
stream.avail_out = left > (uLong)max ? max : (uInt)left;
|
||||
left -= stream.avail_out;
|
||||
}
|
||||
if (stream.avail_in == 0) {
|
||||
stream.avail_in = sourceLen > (uLong)max ? max : (uInt)sourceLen;
|
||||
sourceLen -= stream.avail_in;
|
||||
}
|
||||
err = deflate(&stream, sourceLen ? Z_NO_FLUSH : Z_FINISH);
|
||||
} while (err == Z_OK);
|
||||
|
||||
*destLen = stream.total_out;
|
||||
deflateEnd(&stream);
|
||||
return err == Z_STREAM_END ? Z_OK : err;
|
||||
}
|
||||
|
||||
/**
|
||||
* If the default memLevel or windowBits for deflateInit() is changed,
|
||||
* then this function needs to be updated.
|
||||
*/
|
||||
uLong compressBound(uLong sourceLen) {
|
||||
sourceLen = sourceLen + (sourceLen >> 12) + (sourceLen >> 14) +
|
||||
(sourceLen >> 25) + 13;
|
||||
/* FIXME(cavalcantii): usage of CRC32 Castagnoli as a hash function
|
||||
* for the hash table of symbols used for compression has a side effect
|
||||
* where for compression level [4, 5] it will increase the output buffer
|
||||
* size by 0.1% (i.e. less than 1%) for a high entropy input (i.e. random
|
||||
* data). To avoid a scenario where client code would fail, for safety we
|
||||
* increase the expected output size by 0.8% (i.e. 8x more than the worst
|
||||
* scenario). See: http://crbug.com/990489
|
||||
*/
|
||||
sourceLen += sourceLen >> 7; // Equivalent to 1.0078125
|
||||
return sourceLen;
|
||||
}
|
39
third_party/zlib/crc32.c
vendored
Normal file
39
third_party/zlib/crc32.c
vendored
Normal file
|
@ -0,0 +1,39 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=4 sts=4 sw=4 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 1995-2006, 2010, 2011, 2012, 2016 Mark Adler │
|
||||
│ Use of this source code is governed by the BSD-style licenses that can │
|
||||
│ be found in the third_party/zlib/LICENSE file. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/dce.h"
|
||||
#include "libc/nexgen32e/x86feature.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "third_party/zlib/deflate.h"
|
||||
#include "third_party/zlib/internal.h"
|
||||
#include "third_party/zlib/zutil.h"
|
||||
|
||||
asm(".ident\t\"\\n\\n\
|
||||
zlib (zlib License)\\n\
|
||||
Copyright 1995-2017 Jean-loup Gailly and Mark Adler\"");
|
||||
asm(".include \"libc/disclaimer.inc\"");
|
||||
|
||||
void crc_reset(struct DeflateState *const s) {
|
||||
if (X86_HAVE(PCLMUL)) {
|
||||
crc_fold_init(s);
|
||||
return;
|
||||
}
|
||||
s->strm->adler = crc32(0L, Z_NULL, 0);
|
||||
}
|
||||
|
||||
void crc_finalize(struct DeflateState *const s) {
|
||||
if (X86_HAVE(PCLMUL)) s->strm->adler = crc_fold_512to32(s);
|
||||
}
|
||||
|
||||
void copy_with_crc(z_streamp strm, Bytef *dst, long size) {
|
||||
if (X86_HAVE(PCLMUL)) {
|
||||
crc_fold_copy(strm->state, dst, strm->next_in, size);
|
||||
return;
|
||||
}
|
||||
memcpy(dst, strm->next_in, size);
|
||||
strm->adler = crc32(strm->adler, dst, size);
|
||||
}
|
83
third_party/zlib/crc32concat.c
vendored
Normal file
83
third_party/zlib/crc32concat.c
vendored
Normal file
|
@ -0,0 +1,83 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=4 sts=4 sw=4 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 1995-2017 Jean-loup Gailly and Mark Adler │
|
||||
│ Copyright 2017 The Chromium Authors │
|
||||
│ Use of this source code is governed by the BSD-style licenses that can │
|
||||
│ be found in the third_party/zlib/LICENSE file. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "third_party/zlib/deflate.h"
|
||||
#include "third_party/zlib/internal.h"
|
||||
#include "third_party/zlib/zutil.h"
|
||||
|
||||
asm(".ident\t\"\\n\\n\
|
||||
zlib (zlib License)\\n\
|
||||
Copyright 1995-2017 Jean-loup Gailly and Mark Adler\"");
|
||||
asm(".include \"libc/disclaimer.inc\"");
|
||||
|
||||
#define GF2_DIM 32 /* dimension of GF(2) vectors (length of CRC) */
|
||||
|
||||
static unsigned long gf2_matrix_times(unsigned long *mat, unsigned long vec) {
|
||||
unsigned long sum;
|
||||
sum = 0;
|
||||
while (vec) {
|
||||
if (vec & 1) sum ^= *mat;
|
||||
vec >>= 1;
|
||||
mat++;
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
static void gf2_matrix_square(unsigned long *square, unsigned long *mat) {
|
||||
int n;
|
||||
for (n = 0; n < GF2_DIM; n++) {
|
||||
square[n] = gf2_matrix_times(mat, mat[n]);
|
||||
}
|
||||
}
|
||||
|
||||
uLong crc32_combine(uLong crc1, uLong crc2, int64_t len2) {
|
||||
int n;
|
||||
unsigned long row;
|
||||
unsigned long even[GF2_DIM]; /* even-power-of-two zeros operator */
|
||||
unsigned long odd[GF2_DIM]; /* odd-power-of-two zeros operator */
|
||||
|
||||
/* degenerate case (also disallow negative lengths) */
|
||||
if (len2 <= 0) return crc1;
|
||||
|
||||
/* put operator for one zero bit in odd */
|
||||
odd[0] = 0xedb88320UL; /* CRC-32 polynomial */
|
||||
row = 1;
|
||||
for (n = 1; n < GF2_DIM; n++) {
|
||||
odd[n] = row;
|
||||
row <<= 1;
|
||||
}
|
||||
|
||||
/* put operator for two zero bits in even */
|
||||
gf2_matrix_square(even, odd);
|
||||
|
||||
/* put operator for four zero bits in odd */
|
||||
gf2_matrix_square(odd, even);
|
||||
|
||||
/* apply len2 zeros to crc1 (first square will put the operator for one
|
||||
zero byte, eight zero bits, in even) */
|
||||
do {
|
||||
/* apply zeros operator for this bit of len2 */
|
||||
gf2_matrix_square(even, odd);
|
||||
if (len2 & 1) crc1 = gf2_matrix_times(even, crc1);
|
||||
len2 >>= 1;
|
||||
|
||||
/* if no more bits set, then done */
|
||||
if (len2 == 0) break;
|
||||
|
||||
/* another iteration of the loop with odd and even swapped */
|
||||
gf2_matrix_square(odd, even);
|
||||
if (len2 & 1) crc1 = gf2_matrix_times(odd, crc1);
|
||||
len2 >>= 1;
|
||||
|
||||
/* if no more bits set, then done */
|
||||
} while (len2 != 0);
|
||||
|
||||
/* return combined crc */
|
||||
crc1 ^= crc2;
|
||||
return crc1;
|
||||
}
|
479
third_party/zlib/crcfold.c
vendored
Normal file
479
third_party/zlib/crcfold.c
vendored
Normal file
|
@ -0,0 +1,479 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=4 sts=4 sw=4 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2013 Intel Corporation │
|
||||
│ Use of this source code is governed by the BSD-style licenses that can │
|
||||
│ be found in the third_party/zlib/LICENSE file. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/bits/emmintrin.h"
|
||||
#include "libc/bits/smmintrin.h"
|
||||
#include "libc/bits/tmmintrin.h"
|
||||
#include "libc/bits/wmmintrin.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "third_party/zlib/deflate.h"
|
||||
#include "third_party/zlib/internal.h"
|
||||
|
||||
asm(".ident\t\"\\n\\n\
|
||||
zlib » crc32 parallelized folding (zlib License)\\n\
|
||||
Copyright 2013 Intel Corporation\\n\
|
||||
Authors: Wajdi Feghali,Jim Guilford,Vinodh Gopal,Erdinc Ozturk,Jim Kukunas\"");
|
||||
asm(".include \"libc/disclaimer.inc\"");
|
||||
|
||||
/**
|
||||
* CRC32 parallelized folding w/ PCLMULQDQ instruction.
|
||||
*
|
||||
* Authored by:
|
||||
* Wajdi Feghali <wajdi.k.feghali@intel.com>
|
||||
* Jim Guilford <james.guilford@intel.com>
|
||||
* Vinodh Gopal <vinodh.gopal@intel.com>
|
||||
* Erdinc Ozturk <erdinc.ozturk@intel.com>
|
||||
* Jim Kukunas <james.t.kukunas@linux.intel.com>
|
||||
*
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
#define CRC_LOAD(s) \
|
||||
__m128i xmm_crc0 = _mm_loadu_si128((__m128i *)s->crc0 + 0); \
|
||||
__m128i xmm_crc1 = _mm_loadu_si128((__m128i *)s->crc0 + 1); \
|
||||
__m128i xmm_crc2 = _mm_loadu_si128((__m128i *)s->crc0 + 2); \
|
||||
__m128i xmm_crc3 = _mm_loadu_si128((__m128i *)s->crc0 + 3); \
|
||||
__m128i xmm_crc_part = _mm_loadu_si128((__m128i *)s->crc0 + 4)
|
||||
|
||||
#define CRC_SAVE(s) \
|
||||
_mm_storeu_si128((__m128i *)s->crc0 + 0, xmm_crc0); \
|
||||
_mm_storeu_si128((__m128i *)s->crc0 + 1, xmm_crc1); \
|
||||
_mm_storeu_si128((__m128i *)s->crc0 + 2, xmm_crc2); \
|
||||
_mm_storeu_si128((__m128i *)s->crc0 + 3, xmm_crc3); \
|
||||
_mm_storeu_si128((__m128i *)s->crc0 + 4, xmm_crc_part)
|
||||
|
||||
void crc_fold_init(struct DeflateState *const s) {
|
||||
CRC_LOAD(s);
|
||||
xmm_crc0 = _mm_cvtsi32_si128(0x9db42487);
|
||||
xmm_crc1 = _mm_setzero_si128();
|
||||
xmm_crc2 = _mm_setzero_si128();
|
||||
xmm_crc3 = _mm_setzero_si128();
|
||||
CRC_SAVE(s);
|
||||
s->strm->adler = 0;
|
||||
}
|
||||
|
||||
static inline void fold_1(struct DeflateState *const s, __m128i *xmm_crc0,
|
||||
__m128i *xmm_crc1, __m128i *xmm_crc2,
|
||||
__m128i *xmm_crc3) {
|
||||
const __m128i xmm_fold4 =
|
||||
_mm_set_epi32(0x00000001, 0x54442bd4, 0x00000001, 0xc6e41596);
|
||||
|
||||
__m128i x_tmp3;
|
||||
__m128 ps_crc0, ps_crc3, ps_res;
|
||||
|
||||
x_tmp3 = *xmm_crc3;
|
||||
|
||||
*xmm_crc3 = *xmm_crc0;
|
||||
*xmm_crc0 = _mm_clmulepi64_si128(*xmm_crc0, xmm_fold4, 0x01);
|
||||
*xmm_crc3 = _mm_clmulepi64_si128(*xmm_crc3, xmm_fold4, 0x10);
|
||||
ps_crc0 = _mm_castsi128_ps(*xmm_crc0);
|
||||
ps_crc3 = _mm_castsi128_ps(*xmm_crc3);
|
||||
ps_res = _mm_xor_ps(ps_crc0, ps_crc3);
|
||||
|
||||
*xmm_crc0 = *xmm_crc1;
|
||||
*xmm_crc1 = *xmm_crc2;
|
||||
*xmm_crc2 = x_tmp3;
|
||||
*xmm_crc3 = _mm_castps_si128(ps_res);
|
||||
}
|
||||
|
||||
static inline void fold_2(struct DeflateState *const s, __m128i *xmm_crc0,
|
||||
__m128i *xmm_crc1, __m128i *xmm_crc2,
|
||||
__m128i *xmm_crc3) {
|
||||
const __m128i xmm_fold4 =
|
||||
_mm_set_epi32(0x00000001, 0x54442bd4, 0x00000001, 0xc6e41596);
|
||||
|
||||
__m128i x_tmp3, x_tmp2;
|
||||
__m128 ps_crc0, ps_crc1, ps_crc2, ps_crc3, ps_res31, ps_res20;
|
||||
|
||||
x_tmp3 = *xmm_crc3;
|
||||
x_tmp2 = *xmm_crc2;
|
||||
|
||||
*xmm_crc3 = *xmm_crc1;
|
||||
*xmm_crc1 = _mm_clmulepi64_si128(*xmm_crc1, xmm_fold4, 0x01);
|
||||
*xmm_crc3 = _mm_clmulepi64_si128(*xmm_crc3, xmm_fold4, 0x10);
|
||||
ps_crc3 = _mm_castsi128_ps(*xmm_crc3);
|
||||
ps_crc1 = _mm_castsi128_ps(*xmm_crc1);
|
||||
ps_res31 = _mm_xor_ps(ps_crc3, ps_crc1);
|
||||
|
||||
*xmm_crc2 = *xmm_crc0;
|
||||
*xmm_crc0 = _mm_clmulepi64_si128(*xmm_crc0, xmm_fold4, 0x01);
|
||||
*xmm_crc2 = _mm_clmulepi64_si128(*xmm_crc2, xmm_fold4, 0x10);
|
||||
ps_crc0 = _mm_castsi128_ps(*xmm_crc0);
|
||||
ps_crc2 = _mm_castsi128_ps(*xmm_crc2);
|
||||
ps_res20 = _mm_xor_ps(ps_crc0, ps_crc2);
|
||||
|
||||
*xmm_crc0 = x_tmp2;
|
||||
*xmm_crc1 = x_tmp3;
|
||||
*xmm_crc2 = _mm_castps_si128(ps_res20);
|
||||
*xmm_crc3 = _mm_castps_si128(ps_res31);
|
||||
}
|
||||
|
||||
static inline void fold_3(struct DeflateState *const s, __m128i *xmm_crc0,
|
||||
__m128i *xmm_crc1, __m128i *xmm_crc2,
|
||||
__m128i *xmm_crc3) {
|
||||
const __m128i xmm_fold4 =
|
||||
_mm_set_epi32(0x00000001, 0x54442bd4, 0x00000001, 0xc6e41596);
|
||||
|
||||
__m128i x_tmp3;
|
||||
__m128 ps_crc0, ps_crc1, ps_crc2, ps_crc3, ps_res32, ps_res21, ps_res10;
|
||||
|
||||
x_tmp3 = *xmm_crc3;
|
||||
|
||||
*xmm_crc3 = *xmm_crc2;
|
||||
*xmm_crc2 = _mm_clmulepi64_si128(*xmm_crc2, xmm_fold4, 0x01);
|
||||
*xmm_crc3 = _mm_clmulepi64_si128(*xmm_crc3, xmm_fold4, 0x10);
|
||||
ps_crc2 = _mm_castsi128_ps(*xmm_crc2);
|
||||
ps_crc3 = _mm_castsi128_ps(*xmm_crc3);
|
||||
ps_res32 = _mm_xor_ps(ps_crc2, ps_crc3);
|
||||
|
||||
*xmm_crc2 = *xmm_crc1;
|
||||
*xmm_crc1 = _mm_clmulepi64_si128(*xmm_crc1, xmm_fold4, 0x01);
|
||||
*xmm_crc2 = _mm_clmulepi64_si128(*xmm_crc2, xmm_fold4, 0x10);
|
||||
ps_crc1 = _mm_castsi128_ps(*xmm_crc1);
|
||||
ps_crc2 = _mm_castsi128_ps(*xmm_crc2);
|
||||
ps_res21 = _mm_xor_ps(ps_crc1, ps_crc2);
|
||||
|
||||
*xmm_crc1 = *xmm_crc0;
|
||||
*xmm_crc0 = _mm_clmulepi64_si128(*xmm_crc0, xmm_fold4, 0x01);
|
||||
*xmm_crc1 = _mm_clmulepi64_si128(*xmm_crc1, xmm_fold4, 0x10);
|
||||
ps_crc0 = _mm_castsi128_ps(*xmm_crc0);
|
||||
ps_crc1 = _mm_castsi128_ps(*xmm_crc1);
|
||||
ps_res10 = _mm_xor_ps(ps_crc0, ps_crc1);
|
||||
|
||||
*xmm_crc0 = x_tmp3;
|
||||
*xmm_crc1 = _mm_castps_si128(ps_res10);
|
||||
*xmm_crc2 = _mm_castps_si128(ps_res21);
|
||||
*xmm_crc3 = _mm_castps_si128(ps_res32);
|
||||
}
|
||||
|
||||
static inline void fold_4(struct DeflateState *const s, __m128i *xmm_crc0,
|
||||
__m128i *xmm_crc1, __m128i *xmm_crc2,
|
||||
__m128i *xmm_crc3) {
|
||||
const __m128i xmm_fold4 =
|
||||
_mm_set_epi32(0x00000001, 0x54442bd4, 0x00000001, 0xc6e41596);
|
||||
|
||||
__m128i x_tmp0, x_tmp1, x_tmp2, x_tmp3;
|
||||
__m128 ps_crc0, ps_crc1, ps_crc2, ps_crc3;
|
||||
__m128 ps_t0, ps_t1, ps_t2, ps_t3;
|
||||
__m128 ps_res0, ps_res1, ps_res2, ps_res3;
|
||||
|
||||
x_tmp0 = *xmm_crc0;
|
||||
x_tmp1 = *xmm_crc1;
|
||||
x_tmp2 = *xmm_crc2;
|
||||
x_tmp3 = *xmm_crc3;
|
||||
|
||||
*xmm_crc0 = _mm_clmulepi64_si128(*xmm_crc0, xmm_fold4, 0x01);
|
||||
x_tmp0 = _mm_clmulepi64_si128(x_tmp0, xmm_fold4, 0x10);
|
||||
ps_crc0 = _mm_castsi128_ps(*xmm_crc0);
|
||||
ps_t0 = _mm_castsi128_ps(x_tmp0);
|
||||
ps_res0 = _mm_xor_ps(ps_crc0, ps_t0);
|
||||
|
||||
*xmm_crc1 = _mm_clmulepi64_si128(*xmm_crc1, xmm_fold4, 0x01);
|
||||
x_tmp1 = _mm_clmulepi64_si128(x_tmp1, xmm_fold4, 0x10);
|
||||
ps_crc1 = _mm_castsi128_ps(*xmm_crc1);
|
||||
ps_t1 = _mm_castsi128_ps(x_tmp1);
|
||||
ps_res1 = _mm_xor_ps(ps_crc1, ps_t1);
|
||||
|
||||
*xmm_crc2 = _mm_clmulepi64_si128(*xmm_crc2, xmm_fold4, 0x01);
|
||||
x_tmp2 = _mm_clmulepi64_si128(x_tmp2, xmm_fold4, 0x10);
|
||||
ps_crc2 = _mm_castsi128_ps(*xmm_crc2);
|
||||
ps_t2 = _mm_castsi128_ps(x_tmp2);
|
||||
ps_res2 = _mm_xor_ps(ps_crc2, ps_t2);
|
||||
|
||||
*xmm_crc3 = _mm_clmulepi64_si128(*xmm_crc3, xmm_fold4, 0x01);
|
||||
x_tmp3 = _mm_clmulepi64_si128(x_tmp3, xmm_fold4, 0x10);
|
||||
ps_crc3 = _mm_castsi128_ps(*xmm_crc3);
|
||||
ps_t3 = _mm_castsi128_ps(x_tmp3);
|
||||
ps_res3 = _mm_xor_ps(ps_crc3, ps_t3);
|
||||
|
||||
*xmm_crc0 = _mm_castps_si128(ps_res0);
|
||||
*xmm_crc1 = _mm_castps_si128(ps_res1);
|
||||
*xmm_crc2 = _mm_castps_si128(ps_res2);
|
||||
*xmm_crc3 = _mm_castps_si128(ps_res3);
|
||||
}
|
||||
|
||||
static const unsigned aligned(32) pshufb_shf_table[60] = {
|
||||
0x84838281, 0x88878685, 0x8c8b8a89, 0x008f8e8d, /* shl 15 (16 - 1)/shr1 */
|
||||
0x85848382, 0x89888786, 0x8d8c8b8a, 0x01008f8e, /* shl 14 (16 - 3)/shr2 */
|
||||
0x86858483, 0x8a898887, 0x8e8d8c8b, 0x0201008f, /* shl 13 (16 - 4)/shr3 */
|
||||
0x87868584, 0x8b8a8988, 0x8f8e8d8c, 0x03020100, /* shl 12 (16 - 4)/shr4 */
|
||||
0x88878685, 0x8c8b8a89, 0x008f8e8d, 0x04030201, /* shl 11 (16 - 5)/shr5 */
|
||||
0x89888786, 0x8d8c8b8a, 0x01008f8e, 0x05040302, /* shl 10 (16 - 6)/shr6 */
|
||||
0x8a898887, 0x8e8d8c8b, 0x0201008f, 0x06050403, /* shl 9 (16 - 7)/shr7 */
|
||||
0x8b8a8988, 0x8f8e8d8c, 0x03020100, 0x07060504, /* shl 8 (16 - 8)/shr8 */
|
||||
0x8c8b8a89, 0x008f8e8d, 0x04030201, 0x08070605, /* shl 7 (16 - 9)/shr9 */
|
||||
0x8d8c8b8a, 0x01008f8e, 0x05040302, 0x09080706, /* shl 6 (16 -10)/shr10*/
|
||||
0x8e8d8c8b, 0x0201008f, 0x06050403, 0x0a090807, /* shl 5 (16 -11)/shr11*/
|
||||
0x8f8e8d8c, 0x03020100, 0x07060504, 0x0b0a0908, /* shl 4 (16 -12)/shr12*/
|
||||
0x008f8e8d, 0x04030201, 0x08070605, 0x0c0b0a09, /* shl 3 (16 -13)/shr13*/
|
||||
0x01008f8e, 0x05040302, 0x09080706, 0x0d0c0b0a, /* shl 2 (16 -14)/shr14*/
|
||||
0x0201008f, 0x06050403, 0x0a090807, 0x0e0d0c0b /* shl 1 (16 -15)/shr15*/
|
||||
};
|
||||
|
||||
static void partial_fold(struct DeflateState *const s, const size_t len,
|
||||
__m128i *xmm_crc0, __m128i *xmm_crc1,
|
||||
__m128i *xmm_crc2, __m128i *xmm_crc3,
|
||||
__m128i *xmm_crc_part) {
|
||||
const __m128i xmm_fold4 =
|
||||
_mm_set_epi32(0x00000001, 0x54442bd4, 0x00000001, 0xc6e41596);
|
||||
const __m128i xmm_mask3 = _mm_set1_epi32(0x80808080);
|
||||
|
||||
__m128i xmm_shl, xmm_shr, xmm_tmp1, xmm_tmp2, xmm_tmp3;
|
||||
__m128i xmm_a0_0, xmm_a0_1;
|
||||
__m128 ps_crc3, psa0_0, psa0_1, ps_res;
|
||||
|
||||
{
|
||||
__m128i *wut = (__m128i *)pshufb_shf_table + (len - 1);
|
||||
intptr_t huh = (intptr_t)wut;
|
||||
intptr_t tab = (intptr_t)pshufb_shf_table;
|
||||
if (huh < tab || huh + sizeof(*wut) >= tab + sizeof(pshufb_shf_table)) {
|
||||
abort();
|
||||
}
|
||||
xmm_shl = _mm_load_si128(wut);
|
||||
}
|
||||
|
||||
xmm_shr = xmm_shl;
|
||||
xmm_shr = _mm_xor_si128(xmm_shr, xmm_mask3);
|
||||
|
||||
xmm_a0_0 = _mm_shuffle_epi8(*xmm_crc0, xmm_shl);
|
||||
|
||||
*xmm_crc0 = _mm_shuffle_epi8(*xmm_crc0, xmm_shr);
|
||||
xmm_tmp1 = _mm_shuffle_epi8(*xmm_crc1, xmm_shl);
|
||||
*xmm_crc0 = _mm_or_si128(*xmm_crc0, xmm_tmp1);
|
||||
|
||||
*xmm_crc1 = _mm_shuffle_epi8(*xmm_crc1, xmm_shr);
|
||||
xmm_tmp2 = _mm_shuffle_epi8(*xmm_crc2, xmm_shl);
|
||||
*xmm_crc1 = _mm_or_si128(*xmm_crc1, xmm_tmp2);
|
||||
|
||||
*xmm_crc2 = _mm_shuffle_epi8(*xmm_crc2, xmm_shr);
|
||||
xmm_tmp3 = _mm_shuffle_epi8(*xmm_crc3, xmm_shl);
|
||||
*xmm_crc2 = _mm_or_si128(*xmm_crc2, xmm_tmp3);
|
||||
|
||||
*xmm_crc3 = _mm_shuffle_epi8(*xmm_crc3, xmm_shr);
|
||||
*xmm_crc_part = _mm_shuffle_epi8(*xmm_crc_part, xmm_shl);
|
||||
*xmm_crc3 = _mm_or_si128(*xmm_crc3, *xmm_crc_part);
|
||||
|
||||
xmm_a0_1 = _mm_clmulepi64_si128(xmm_a0_0, xmm_fold4, 0x10);
|
||||
xmm_a0_0 = _mm_clmulepi64_si128(xmm_a0_0, xmm_fold4, 0x01);
|
||||
|
||||
ps_crc3 = _mm_castsi128_ps(*xmm_crc3);
|
||||
psa0_0 = _mm_castsi128_ps(xmm_a0_0);
|
||||
psa0_1 = _mm_castsi128_ps(xmm_a0_1);
|
||||
|
||||
ps_res = _mm_xor_ps(ps_crc3, psa0_0);
|
||||
ps_res = _mm_xor_ps(ps_res, psa0_1);
|
||||
|
||||
*xmm_crc3 = _mm_castps_si128(ps_res);
|
||||
}
|
||||
|
||||
void crc_fold_copy(struct DeflateState *const s, unsigned char *dst,
|
||||
const unsigned char *src, long len) {
|
||||
unsigned long algn_diff;
|
||||
__m128i xmm_t0, xmm_t1, xmm_t2, xmm_t3;
|
||||
|
||||
CRC_LOAD(s);
|
||||
|
||||
if (len < 16) {
|
||||
if (len == 0) return;
|
||||
goto partial;
|
||||
}
|
||||
|
||||
algn_diff = 0 - ((uintptr_t)src & 0xF);
|
||||
if (algn_diff) {
|
||||
xmm_crc_part = _mm_loadu_si128((__m128i *)src);
|
||||
_mm_storeu_si128((__m128i *)dst, xmm_crc_part);
|
||||
|
||||
dst += algn_diff;
|
||||
src += algn_diff;
|
||||
len -= algn_diff;
|
||||
|
||||
partial_fold(s, algn_diff, &xmm_crc0, &xmm_crc1, &xmm_crc2, &xmm_crc3,
|
||||
&xmm_crc_part);
|
||||
}
|
||||
|
||||
while ((len -= 64) >= 0) {
|
||||
xmm_t0 = _mm_load_si128((__m128i *)src);
|
||||
xmm_t1 = _mm_load_si128((__m128i *)src + 1);
|
||||
xmm_t2 = _mm_load_si128((__m128i *)src + 2);
|
||||
xmm_t3 = _mm_load_si128((__m128i *)src + 3);
|
||||
|
||||
fold_4(s, &xmm_crc0, &xmm_crc1, &xmm_crc2, &xmm_crc3);
|
||||
|
||||
_mm_storeu_si128((__m128i *)dst, xmm_t0);
|
||||
_mm_storeu_si128((__m128i *)dst + 1, xmm_t1);
|
||||
_mm_storeu_si128((__m128i *)dst + 2, xmm_t2);
|
||||
_mm_storeu_si128((__m128i *)dst + 3, xmm_t3);
|
||||
|
||||
xmm_crc0 = _mm_xor_si128(xmm_crc0, xmm_t0);
|
||||
xmm_crc1 = _mm_xor_si128(xmm_crc1, xmm_t1);
|
||||
xmm_crc2 = _mm_xor_si128(xmm_crc2, xmm_t2);
|
||||
xmm_crc3 = _mm_xor_si128(xmm_crc3, xmm_t3);
|
||||
|
||||
src += 64;
|
||||
dst += 64;
|
||||
}
|
||||
|
||||
/*
|
||||
* len = num bytes left - 64
|
||||
*/
|
||||
if (len + 16 >= 0) {
|
||||
len += 16;
|
||||
|
||||
xmm_t0 = _mm_load_si128((__m128i *)src);
|
||||
xmm_t1 = _mm_load_si128((__m128i *)src + 1);
|
||||
xmm_t2 = _mm_load_si128((__m128i *)src + 2);
|
||||
|
||||
fold_3(s, &xmm_crc0, &xmm_crc1, &xmm_crc2, &xmm_crc3);
|
||||
|
||||
_mm_storeu_si128((__m128i *)dst, xmm_t0);
|
||||
_mm_storeu_si128((__m128i *)dst + 1, xmm_t1);
|
||||
_mm_storeu_si128((__m128i *)dst + 2, xmm_t2);
|
||||
|
||||
xmm_crc1 = _mm_xor_si128(xmm_crc1, xmm_t0);
|
||||
xmm_crc2 = _mm_xor_si128(xmm_crc2, xmm_t1);
|
||||
xmm_crc3 = _mm_xor_si128(xmm_crc3, xmm_t2);
|
||||
|
||||
if (len == 0) goto done;
|
||||
|
||||
dst += 48;
|
||||
src += 48;
|
||||
} else if (len + 32 >= 0) {
|
||||
len += 32;
|
||||
|
||||
xmm_t0 = _mm_load_si128((__m128i *)src);
|
||||
xmm_t1 = _mm_load_si128((__m128i *)src + 1);
|
||||
|
||||
fold_2(s, &xmm_crc0, &xmm_crc1, &xmm_crc2, &xmm_crc3);
|
||||
|
||||
_mm_storeu_si128((__m128i *)dst, xmm_t0);
|
||||
_mm_storeu_si128((__m128i *)dst + 1, xmm_t1);
|
||||
|
||||
xmm_crc2 = _mm_xor_si128(xmm_crc2, xmm_t0);
|
||||
xmm_crc3 = _mm_xor_si128(xmm_crc3, xmm_t1);
|
||||
|
||||
if (len == 0) goto done;
|
||||
|
||||
dst += 32;
|
||||
src += 32;
|
||||
} else if (len + 48 >= 0) {
|
||||
len += 48;
|
||||
|
||||
xmm_t0 = _mm_load_si128((__m128i *)src);
|
||||
|
||||
fold_1(s, &xmm_crc0, &xmm_crc1, &xmm_crc2, &xmm_crc3);
|
||||
|
||||
_mm_storeu_si128((__m128i *)dst, xmm_t0);
|
||||
|
||||
xmm_crc3 = _mm_xor_si128(xmm_crc3, xmm_t0);
|
||||
|
||||
if (len == 0) goto done;
|
||||
|
||||
dst += 16;
|
||||
src += 16;
|
||||
} else {
|
||||
len += 64;
|
||||
if (len == 0) goto done;
|
||||
}
|
||||
|
||||
partial:
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
/* VS does not permit the use of _mm_set_epi64x in 32-bit builds */
|
||||
{
|
||||
int32_t parts[4] = {0, 0, 0, 0};
|
||||
memcpy(&parts, src, len);
|
||||
xmm_crc_part = _mm_set_epi32(parts[3], parts[2], parts[1], parts[0]);
|
||||
}
|
||||
#else
|
||||
{
|
||||
int64_t parts[2] = {0, 0};
|
||||
memcpy(&parts, src, len);
|
||||
xmm_crc_part = _mm_set_epi64x(parts[1], parts[0]);
|
||||
}
|
||||
#endif
|
||||
|
||||
_mm_storeu_si128((__m128i *)dst, xmm_crc_part);
|
||||
partial_fold(s, len, &xmm_crc0, &xmm_crc1, &xmm_crc2, &xmm_crc3,
|
||||
&xmm_crc_part);
|
||||
done:
|
||||
CRC_SAVE(s);
|
||||
}
|
||||
|
||||
static const __m128i kCrcFold512[] = {
|
||||
{0xffffffffffffffffull, 0x0000000000000000ull},
|
||||
{0xffffffff00000000ull, 0xffffffffffffffffull},
|
||||
{0x00000000ccaa009eull, 0x00000001751997d0ull}, /* 2: k1 */
|
||||
{0x00000000ccaa009eull, 0x0000000163cd6124ull}, /* 3: k5 */
|
||||
{0x00000001f7011640ull, 0x00000001db710640ull} /* 4: k7 */
|
||||
};
|
||||
|
||||
unsigned crc_fold_512to32(struct DeflateState *const s) {
|
||||
const __m128i xmm_mask = kCrcFold512[0];
|
||||
const __m128i xmm_mask2 = kCrcFold512[1];
|
||||
|
||||
unsigned crc;
|
||||
__m128i x_tmp0, x_tmp1, x_tmp2, crc_fold;
|
||||
|
||||
CRC_LOAD(s);
|
||||
|
||||
/*
|
||||
* k1
|
||||
*/
|
||||
crc_fold = kCrcFold512[2];
|
||||
|
||||
x_tmp0 = _mm_clmulepi64_si128(xmm_crc0, crc_fold, 0x10);
|
||||
xmm_crc0 = _mm_clmulepi64_si128(xmm_crc0, crc_fold, 0x01);
|
||||
xmm_crc1 = _mm_xor_si128(xmm_crc1, x_tmp0);
|
||||
xmm_crc1 = _mm_xor_si128(xmm_crc1, xmm_crc0);
|
||||
|
||||
x_tmp1 = _mm_clmulepi64_si128(xmm_crc1, crc_fold, 0x10);
|
||||
xmm_crc1 = _mm_clmulepi64_si128(xmm_crc1, crc_fold, 0x01);
|
||||
xmm_crc2 = _mm_xor_si128(xmm_crc2, x_tmp1);
|
||||
xmm_crc2 = _mm_xor_si128(xmm_crc2, xmm_crc1);
|
||||
|
||||
x_tmp2 = _mm_clmulepi64_si128(xmm_crc2, crc_fold, 0x10);
|
||||
xmm_crc2 = _mm_clmulepi64_si128(xmm_crc2, crc_fold, 0x01);
|
||||
xmm_crc3 = _mm_xor_si128(xmm_crc3, x_tmp2);
|
||||
xmm_crc3 = _mm_xor_si128(xmm_crc3, xmm_crc2);
|
||||
|
||||
/*
|
||||
* k5
|
||||
*/
|
||||
crc_fold = kCrcFold512[3];
|
||||
|
||||
xmm_crc0 = xmm_crc3;
|
||||
xmm_crc3 = _mm_clmulepi64_si128(xmm_crc3, crc_fold, 0);
|
||||
xmm_crc0 = _mm_srli_si128(xmm_crc0, 8);
|
||||
xmm_crc3 = _mm_xor_si128(xmm_crc3, xmm_crc0);
|
||||
|
||||
xmm_crc0 = xmm_crc3;
|
||||
xmm_crc3 = _mm_slli_si128(xmm_crc3, 4);
|
||||
xmm_crc3 = _mm_clmulepi64_si128(xmm_crc3, crc_fold, 0x10);
|
||||
xmm_crc3 = _mm_xor_si128(xmm_crc3, xmm_crc0);
|
||||
xmm_crc3 = _mm_and_si128(xmm_crc3, xmm_mask2);
|
||||
|
||||
/*
|
||||
* k7
|
||||
*/
|
||||
xmm_crc1 = xmm_crc3;
|
||||
xmm_crc2 = xmm_crc3;
|
||||
crc_fold = kCrcFold512[4];
|
||||
|
||||
xmm_crc3 = _mm_clmulepi64_si128(xmm_crc3, crc_fold, 0);
|
||||
xmm_crc3 = _mm_xor_si128(xmm_crc3, xmm_crc2);
|
||||
xmm_crc3 = _mm_and_si128(xmm_crc3, xmm_mask);
|
||||
|
||||
xmm_crc2 = xmm_crc3;
|
||||
xmm_crc3 = _mm_clmulepi64_si128(xmm_crc3, crc_fold, 0x10);
|
||||
xmm_crc3 = _mm_xor_si128(xmm_crc3, xmm_crc2);
|
||||
xmm_crc3 = _mm_xor_si128(xmm_crc3, xmm_crc1);
|
||||
|
||||
crc = _mm_extract_epi32(xmm_crc3, 2);
|
||||
return ~crc;
|
||||
CRC_SAVE(s); /* TODO(jart): wut? */
|
||||
}
|
1871
third_party/zlib/deflate.c
vendored
Normal file
1871
third_party/zlib/deflate.c
vendored
Normal file
File diff suppressed because it is too large
Load diff
321
third_party/zlib/deflate.h
vendored
Normal file
321
third_party/zlib/deflate.h
vendored
Normal file
|
@ -0,0 +1,321 @@
|
|||
#ifndef DEFLATE_H
|
||||
#define DEFLATE_H
|
||||
#include "third_party/zlib/zutil.h"
|
||||
|
||||
/* define NO_GZIP when compiling if you want to disable gzip header and
|
||||
trailer creation by deflate(). NO_GZIP would be used to avoid linking
|
||||
in the crc code when it is not needed. For shared libraries, gzip
|
||||
encoding should be left enabled. */
|
||||
#ifndef NO_GZIP
|
||||
#define GZIP
|
||||
#endif
|
||||
|
||||
/* number of length codes, not counting the special END_BLOCK code */
|
||||
#define LENGTH_CODES 29
|
||||
|
||||
/* number of literal bytes 0..255 */
|
||||
#define LITERALS 256
|
||||
|
||||
/* number of Literal or Length codes, including the END_BLOCK code */
|
||||
#define L_CODES (LITERALS + 1 + LENGTH_CODES)
|
||||
|
||||
/* number of distance codes */
|
||||
#define D_CODES 30
|
||||
|
||||
/* number of codes used to transfer the bit lengths */
|
||||
#define BL_CODES 19
|
||||
|
||||
/* maximum heap size */
|
||||
#define HEAP_SIZE (2 * L_CODES + 1)
|
||||
|
||||
/* All codes must not exceed MAX_BITS bits */
|
||||
#define MAX_BITS 15
|
||||
|
||||
/* size of bit buffer in bi_buf */
|
||||
#define Buf_size 16
|
||||
|
||||
#define DIST_CODE_LEN 512 /* see definition of array dist_code below */
|
||||
|
||||
#define INIT_STATE 42 /* zlib header -> BUSY_STATE */
|
||||
#ifdef GZIP
|
||||
#define GZIP_STATE 57 /* gzip header -> BUSY_STATE | EXTRA_STATE */
|
||||
#endif
|
||||
#define EXTRA_STATE 69 /* gzip extra block -> NAME_STATE */
|
||||
#define NAME_STATE 73 /* gzip file name -> COMMENT_STATE */
|
||||
#define COMMENT_STATE 91 /* gzip comment -> HCRC_STATE */
|
||||
#define HCRC_STATE 103 /* gzip header CRC -> BUSY_STATE */
|
||||
#define BUSY_STATE 113 /* deflate -> FINISH_STATE */
|
||||
#define FINISH_STATE 666 /* stream complete */
|
||||
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
/* Data structure describing a single value and its code string. */
|
||||
typedef struct ct_data_s {
|
||||
union {
|
||||
uint16_t freq; /* frequency count */
|
||||
uint16_t code; /* bit string */
|
||||
} fc;
|
||||
union {
|
||||
uint16_t dad; /* father node in Huffman tree */
|
||||
uint16_t len; /* length of bit string */
|
||||
} dl;
|
||||
} ct_data;
|
||||
|
||||
#define Freq fc.freq
|
||||
#define Code fc.code
|
||||
#define Dad dl.dad
|
||||
#define Len dl.len
|
||||
|
||||
typedef struct static_tree_desc_s static_tree_desc;
|
||||
|
||||
typedef struct tree_desc_s {
|
||||
ct_data *dyn_tree; /* the dynamic tree */
|
||||
int max_code; /* largest code with non zero frequency */
|
||||
const static_tree_desc *stat_desc; /* the corresponding static tree */
|
||||
} tree_desc;
|
||||
|
||||
typedef uint16_t Pos;
|
||||
typedef Pos Posf;
|
||||
typedef unsigned IPos;
|
||||
|
||||
/* A Pos is an index in the character window. We use short instead of int to
|
||||
* save space in the various tables. IPos is used only for parameter passing.
|
||||
*/
|
||||
|
||||
struct DeflateState {
|
||||
z_streamp strm; /* pointer back to this zlib stream */
|
||||
int status; /* as the name implies */
|
||||
Bytef *pending_buf; /* output still pending */
|
||||
uint64_t pending_buf_size; /* size of pending_buf */
|
||||
Bytef *pending_out; /* next pending byte to output to the stream */
|
||||
uint64_t pending; /* nb of bytes in the pending buffer */
|
||||
int wrap; /* bit 0 true for zlib, bit 1 true for gzip */
|
||||
gz_headerp gzhead; /* gzip header information to write */
|
||||
uint64_t gzindex; /* where in extra, name, or comment */
|
||||
Byte method; /* can only be DEFLATED */
|
||||
int last_flush; /* value of flush param for previous deflate call */
|
||||
unsigned crc0[4 * 5];
|
||||
/* used by deflate.c: */
|
||||
|
||||
uInt w_size; /* LZ77 window size (32K by default) */
|
||||
uInt w_bits; /* log2(w_size) (8..16) */
|
||||
uInt w_mask; /* w_size - 1 */
|
||||
|
||||
/* Sliding window. Input bytes are read into the second half of the
|
||||
window, and move to the first half later to keep a dictionary of at
|
||||
least wSize bytes. With this organization, matches are limited to a
|
||||
distance of wSize-MAX_MATCH bytes, but this ensures that IO is
|
||||
always performed with a length multiple of the block size. Also, it
|
||||
limits the window size to 64K, which is quite useful on MSDOS. To
|
||||
do: use the user input buffer as sliding window. */
|
||||
Bytef *window;
|
||||
|
||||
/* Actual size of window: 2*wSize, except when the user input buffer
|
||||
is directly used as sliding window. */
|
||||
uint64_t window_size;
|
||||
|
||||
/* Link to older string with same hash index. To limit the size of
|
||||
this array to 64K, this link is maintained only for the last 32K
|
||||
strings. Index in this array is thus a window index modulo 32K. */
|
||||
Posf *prev;
|
||||
|
||||
Posf *head; /* Heads of the hash chains or NIL. */
|
||||
|
||||
uInt ins_h; /* hash index of string to be inserted */
|
||||
uInt hash_size; /* number of elements in hash table */
|
||||
uInt hash_bits; /* log2(hash_size) */
|
||||
uInt hash_mask; /* hash_size-1 */
|
||||
|
||||
/* Number of bits by which ins_h must be shifted at each input step.
|
||||
It must be such that after MIN_MATCH steps, the oldest byte no
|
||||
longer takes part in the hash key, that is: hash_shift * MIN_MATCH
|
||||
>= hash_bits */
|
||||
uInt hash_shift;
|
||||
|
||||
/* Window position at the beginning of the current output block. Gets
|
||||
negative when the window is moved backwards. */
|
||||
long block_start;
|
||||
|
||||
uInt match_length; /* length of best match */
|
||||
IPos prev_match; /* previous match */
|
||||
int match_available; /* set if previous match exists */
|
||||
uInt strstart; /* start of string to insert */
|
||||
uInt match_start; /* start of matching string */
|
||||
uInt lookahead; /* number of valid bytes ahead in window */
|
||||
|
||||
/* Length of the best match at previous step. Matches not greater than
|
||||
this are discarded. This is used in the lazy match evaluation. */
|
||||
uInt prev_length;
|
||||
|
||||
/* To speed up deflation, hash chains are never searched beyond this
|
||||
length. A higher limit improves compression ratio but degrades the
|
||||
speed. */
|
||||
uInt max_chain_length;
|
||||
|
||||
/* Attempt to find a better match only when the current match is
|
||||
strictly smaller than this value. This mechanism is used only for
|
||||
compression levels >= 4. */
|
||||
uInt max_lazy_match;
|
||||
|
||||
/* Insert new strings in the hash table only if the match length is not
|
||||
greater than this length. This saves time but degrades compression.
|
||||
max_insert_length is used only for compression levels <= 3. */
|
||||
#define max_insert_length max_lazy_match
|
||||
|
||||
int level; /* compression level (1..9) */
|
||||
int strategy; /* favor or force Huffman coding*/
|
||||
|
||||
/* Use a faster search when the previous match is longer than this */
|
||||
uInt good_match;
|
||||
|
||||
int nice_match; /* Stop searching when current match exceeds this */
|
||||
|
||||
/* used by trees.c: */
|
||||
/* Didn't use ct_data typedef below to suppress compiler warning */
|
||||
struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */
|
||||
struct ct_data_s dyn_dtree[2 * D_CODES + 1]; /* distance tree */
|
||||
struct ct_data_s bl_tree[2 * BL_CODES + 1]; /* Huffman tree for bit lengths */
|
||||
|
||||
struct tree_desc_s l_desc; /* desc. for literal tree */
|
||||
struct tree_desc_s d_desc; /* desc. for distance tree */
|
||||
struct tree_desc_s bl_desc; /* desc. for bit length tree */
|
||||
|
||||
/* number of codes at each bit length for an optimal tree */
|
||||
uint16_t bl_count[MAX_BITS + 1];
|
||||
|
||||
/* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not
|
||||
used. The same heap array is used to build all trees. */
|
||||
int heap[2 * L_CODES + 1]; /* heap used to build the Huffman trees */
|
||||
int heap_len; /* number of elements in the heap */
|
||||
int heap_max; /* element of largest frequency */
|
||||
|
||||
/* Depth of each subtree used as tie breaker for trees of equal
|
||||
frequency. */
|
||||
uint8_t depth[2 * L_CODES + 1];
|
||||
|
||||
uint8_t *sym_buf; /* buffer for distances and literals/lengths */
|
||||
|
||||
/* Size of match buffer for literals/lengths. There are 4 reasons for
|
||||
limiting lit_bufsize to 64K:
|
||||
- frequencies can be kept in 16 bit counters
|
||||
- if compression is not successful for the first block, all input
|
||||
data is still in the window so we can still emit a stored block even
|
||||
when input comes from standard input. (This can also be done for
|
||||
all blocks if lit_bufsize is not greater than 32K.)
|
||||
- if compression is not successful for a file smaller than 64K, we can
|
||||
even emit a stored file instead of a stored block (saving 5 bytes).
|
||||
This is applicable only for zip (not gzip or zlib).
|
||||
- creating new Huffman trees less frequently may not provide fast
|
||||
adaptation to changes in the input data statistics. (Take for
|
||||
example a binary file with poorly compressible code followed by
|
||||
a highly compressible string table.) Smaller buffer sizes give
|
||||
fast adaptation but have of course the overhead of transmitting
|
||||
trees more frequently.
|
||||
- I can't count above 4 */
|
||||
uInt lit_bufsize;
|
||||
|
||||
uInt sym_next; /* running index in sym_buf */
|
||||
uInt sym_end; /* symbol table full when sym_next reaches this */
|
||||
|
||||
uint64_t opt_len; /* bit length of current block with optimal trees */
|
||||
uint64_t static_len; /* bit length of current block with static trees */
|
||||
uInt matches; /* number of string matches in current block */
|
||||
uInt insert; /* bytes at end of window left to insert */
|
||||
|
||||
#ifdef ZLIB_DEBUG
|
||||
uint64_t compressed_len; /* total bit length of compressed file mod 2^32 */
|
||||
uint64_t bits_sent; /* bit length of compressed data sent mod 2^32 */
|
||||
#endif
|
||||
|
||||
/* Output buffer. bits are inserted starting at the bottom (least
|
||||
significant bits). */
|
||||
uint16_t bi_buf;
|
||||
|
||||
/* Number of valid bits in bi_buf. All bits above the last valid bit
|
||||
are always zero. */
|
||||
int bi_valid;
|
||||
|
||||
/* High water mark offset in window for initialized bytes -- bytes
|
||||
above this are set to zero in order to avoid memory check warnings
|
||||
when longest match routines access bytes past the input. This is
|
||||
then updated to the new high water mark. */
|
||||
uint64_t high_water;
|
||||
};
|
||||
|
||||
/* Output a byte on the stream.
|
||||
* IN assertion: there is enough room in pending_buf.
|
||||
*/
|
||||
#define put_byte(s, c) \
|
||||
{ s->pending_buf[s->pending++] = (Bytef)(c); }
|
||||
|
||||
#define MIN_LOOKAHEAD (MAX_MATCH + MIN_MATCH + 1)
|
||||
/* Minimum amount of lookahead, except at the end of the input file.
|
||||
* See deflate.c for comments about the MIN_MATCH+1.
|
||||
*/
|
||||
|
||||
#define MAX_DIST(s) ((s)->w_size - MIN_LOOKAHEAD)
|
||||
/* In order to simplify the code, particularly on 16 bit machines, match
|
||||
* distances are limited to MAX_DIST instead of WSIZE.
|
||||
*/
|
||||
|
||||
#define WIN_INIT MAX_MATCH
|
||||
/* Number of bytes after end of data in window to initialize in order to avoid
|
||||
memory checker errors from longest match routines */
|
||||
|
||||
/* in trees.c */
|
||||
void _tr_init(struct DeflateState *s) hidden;
|
||||
int _tr_tally(struct DeflateState *s, unsigned dist, unsigned lc) hidden;
|
||||
void _tr_flush_block(struct DeflateState *s, charf *buf, uint64_t stored_len,
|
||||
int last) hidden;
|
||||
void _tr_flush_bits(struct DeflateState *s) hidden;
|
||||
void _tr_align(struct DeflateState *s) hidden;
|
||||
void _tr_stored_block(struct DeflateState *s, charf *buf, uint64_t stored_len,
|
||||
int last) hidden;
|
||||
|
||||
/* Mapping from a distance to a distance code. dist is the distance - 1
|
||||
* and must not have side effects. kZlibDistCode[256] and
|
||||
* kZlibDistCode[257] are never used.
|
||||
*/
|
||||
#define d_code(dist) \
|
||||
((dist) < 256 ? kZlibDistCode[dist] : kZlibDistCode[256 + ((dist) >> 7)])
|
||||
|
||||
#ifndef ZLIB_DEBUG
|
||||
/* Inline versions of _tr_tally for speed: */
|
||||
|
||||
extern const ct_data kZlibStaticDtree[D_CODES] hidden;
|
||||
extern const ct_data kZlibStaticLtree[L_CODES + 2] hidden;
|
||||
extern const int kZlibBaseDist[D_CODES] hidden;
|
||||
extern const int kZlibBaseLength[LENGTH_CODES] hidden;
|
||||
extern const uint8_t kZlibDistCode[DIST_CODE_LEN] hidden;
|
||||
extern const uint8_t kZlibLengthCode[MAX_MATCH - MIN_MATCH + 1] hidden;
|
||||
|
||||
#define _tr_tally_lit(s, c, flush) \
|
||||
{ \
|
||||
uint8_t cc = (c); \
|
||||
s->sym_buf[s->sym_next++] = 0; \
|
||||
s->sym_buf[s->sym_next++] = 0; \
|
||||
s->sym_buf[s->sym_next++] = cc; \
|
||||
s->dyn_ltree[cc].Freq++; \
|
||||
flush = (s->sym_next == s->sym_end); \
|
||||
}
|
||||
#define _tr_tally_dist(s, distance, length, flush) \
|
||||
{ \
|
||||
uint8_t len = (uint8_t)(length); \
|
||||
uint16_t dist = (uint16_t)(distance); \
|
||||
s->sym_buf[s->sym_next++] = dist; \
|
||||
s->sym_buf[s->sym_next++] = dist >> 8; \
|
||||
s->sym_buf[s->sym_next++] = len; \
|
||||
dist--; \
|
||||
s->dyn_ltree[kZlibLengthCode[len] + LITERALS + 1].Freq++; \
|
||||
s->dyn_dtree[d_code(dist)].Freq++; \
|
||||
flush = (s->sym_next == s->sym_end); \
|
||||
}
|
||||
#else
|
||||
#define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c)
|
||||
#define _tr_tally_dist(s, distance, length, flush) \
|
||||
flush = _tr_tally(s, distance, length)
|
||||
#endif
|
||||
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* DEFLATE_H */
|
29
third_party/zlib/deflateinit.S
vendored
Normal file
29
third_party/zlib/deflateinit.S
vendored
Normal file
|
@ -0,0 +1,29 @@
|
|||
/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
|
||||
│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "third_party/zlib/zlib.h"
|
||||
#include "libc/macros.h"
|
||||
|
||||
deflateInit:
|
||||
mov $Z_DEFLATED,%edx
|
||||
mov $MAX_WBITS,%ecx
|
||||
mov $DEF_MEM_LEVEL,%r8d
|
||||
mov $Z_DEFAULT_STRATEGY,%r9d
|
||||
jmp deflateInit2
|
||||
.endfn deflateInit,globl
|
173
third_party/zlib/deflatesse.c
vendored
Normal file
173
third_party/zlib/deflatesse.c
vendored
Normal file
|
@ -0,0 +1,173 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=4 sts=4 sw=4 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2013 Intel Corporation │
|
||||
│ Use of this source code is governed by the BSD-style licenses that can │
|
||||
│ be found in the third_party/zlib/LICENSE file. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/bits/emmintrin.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "third_party/zlib/deflate.h"
|
||||
#include "third_party/zlib/internal.h"
|
||||
#include "third_party/zlib/zutil.h"
|
||||
|
||||
asm(".ident\t\"\\n\\n\
|
||||
zlib » sse2 fill window (zlib License)\\n\
|
||||
Copyright 2013 Intel Corporation\\n\
|
||||
Authors: Arjan van de Ven, Jim Kukunas\"");
|
||||
asm(".include \"libc/disclaimer.inc\"");
|
||||
|
||||
/**
|
||||
* @fileoverview Fill Window with SSE2-optimized hash shifting
|
||||
*/
|
||||
|
||||
#define UPDATE_HASH(s, h, i) \
|
||||
{ \
|
||||
if (s->level < 6) { \
|
||||
h = (3483 * (s->window[i]) + 23081 * (s->window[i + 1]) + \
|
||||
6954 * (s->window[i + 2]) + 20947 * (s->window[i + 3])) & \
|
||||
s->hash_mask; \
|
||||
} else { \
|
||||
h = (25881 * (s->window[i]) + 24674 * (s->window[i + 1]) + \
|
||||
25811 * (s->window[i + 2])) & \
|
||||
s->hash_mask; \
|
||||
} \
|
||||
}
|
||||
|
||||
void fill_window_sse(struct DeflateState *s) {
|
||||
const __m128i xmm_wsize = _mm_set1_epi16(s->w_size);
|
||||
|
||||
register unsigned n;
|
||||
register Posf *p;
|
||||
unsigned more; /* Amount of free space at the end of the window. */
|
||||
uInt wsize = s->w_size;
|
||||
|
||||
Assert(s->lookahead < MIN_LOOKAHEAD, "already enough lookahead");
|
||||
|
||||
do {
|
||||
more = (unsigned)(s->window_size - (uint64_t)s->lookahead -
|
||||
(uint64_t)s->strstart);
|
||||
|
||||
/* Deal with !@#$% 64K limit: */
|
||||
if (sizeof(int) <= 2) {
|
||||
if (more == 0 && s->strstart == 0 && s->lookahead == 0) {
|
||||
more = wsize;
|
||||
|
||||
} else if (more == (unsigned)(-1)) {
|
||||
/* Very unlikely, but possible on 16 bit machine if
|
||||
* strstart == 0 && lookahead == 1 (input done a byte at time)
|
||||
*/
|
||||
more--;
|
||||
}
|
||||
}
|
||||
|
||||
/* If the window is almost full and there is insufficient lookahead,
|
||||
* move the upper half to the lower one to make room in the upper half.
|
||||
*/
|
||||
if (s->strstart >= wsize + MAX_DIST(s)) {
|
||||
memcpy(s->window, s->window + wsize, (unsigned)wsize);
|
||||
s->match_start -= wsize;
|
||||
s->strstart -= wsize; /* we now have strstart >= MAX_DIST */
|
||||
s->block_start -= (long)wsize;
|
||||
|
||||
/* Slide the hash table (could be avoided with 32 bit values
|
||||
at the expense of memory usage). We slide even when level == 0
|
||||
to keep the hash table consistent if we switch back to level > 0
|
||||
later. (Using level 0 permanently is not an optimal usage of
|
||||
zlib, so we don't care about this pathological case.)
|
||||
*/
|
||||
n = s->hash_size;
|
||||
p = &s->head[n];
|
||||
p -= 8;
|
||||
do {
|
||||
__m128i value, result;
|
||||
value = _mm_loadu_si128((__m128i *)p);
|
||||
result = _mm_subs_epu16(value, xmm_wsize);
|
||||
_mm_storeu_si128((__m128i *)p, result);
|
||||
p -= 8;
|
||||
n -= 8;
|
||||
} while (n > 0);
|
||||
|
||||
n = wsize;
|
||||
#ifndef FASTEST
|
||||
p = &s->prev[n];
|
||||
p -= 8;
|
||||
do {
|
||||
__m128i value, result;
|
||||
value = _mm_loadu_si128((__m128i *)p);
|
||||
result = _mm_subs_epu16(value, xmm_wsize);
|
||||
_mm_storeu_si128((__m128i *)p, result);
|
||||
p -= 8;
|
||||
n -= 8;
|
||||
} while (n > 0);
|
||||
#endif
|
||||
more += wsize;
|
||||
}
|
||||
if (s->strm->avail_in == 0) break;
|
||||
|
||||
/* If there was no sliding:
|
||||
* strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 &&
|
||||
* more == window_size - lookahead - strstart
|
||||
* => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1)
|
||||
* => more >= window_size - 2*WSIZE + 2
|
||||
* In the BIG_MEM or MMAP case (not yet supported),
|
||||
* window_size == input_size + MIN_LOOKAHEAD &&
|
||||
* strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD.
|
||||
* Otherwise, window_size == 2*WSIZE so more >= 2.
|
||||
* If there was sliding, more >= WSIZE. So in all cases, more >= 2.
|
||||
*/
|
||||
Assert(more >= 2, "more < 2");
|
||||
|
||||
n = deflate_read_buf(s->strm, s->window + s->strstart + s->lookahead, more);
|
||||
s->lookahead += n;
|
||||
|
||||
/* Initialize the hash value now that we have some input: */
|
||||
if (s->lookahead >= MIN_MATCH) {
|
||||
uInt str = s->strstart;
|
||||
s->ins_h = s->window[str];
|
||||
if (str >= 1) UPDATE_HASH(s, s->ins_h, str + 1 - (MIN_MATCH - 1));
|
||||
#if MIN_MATCH != 3
|
||||
Call UPDATE_HASH() MIN_MATCH - 3 more times
|
||||
#endif
|
||||
}
|
||||
/* If the whole input has less than MIN_MATCH bytes, ins_h is garbage,
|
||||
* but this is not important since only literal bytes will be emitted.
|
||||
*/
|
||||
|
||||
} while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0);
|
||||
|
||||
/* If the WIN_INIT bytes after the end of the current data have never been
|
||||
* written, then zero those bytes in order to avoid memory check reports of
|
||||
* the use of uninitialized (or uninitialised as Julian writes) bytes by
|
||||
* the longest match routines. Update the high water mark for the next
|
||||
* time through here. WIN_INIT is set to MAX_MATCH since the longest match
|
||||
* routines allow scanning to strstart + MAX_MATCH, ignoring lookahead.
|
||||
*/
|
||||
if (s->high_water < s->window_size) {
|
||||
uint64_t curr = s->strstart + (uint64_t)(s->lookahead);
|
||||
uint64_t init;
|
||||
|
||||
if (s->high_water < curr) {
|
||||
/* Previous high water mark below current data -- zero WIN_INIT
|
||||
* bytes or up to end of window, whichever is less.
|
||||
*/
|
||||
init = s->window_size - curr;
|
||||
if (init > WIN_INIT) init = WIN_INIT;
|
||||
memset(s->window + curr, 0, init);
|
||||
s->high_water = curr + init;
|
||||
} else if (s->high_water < (uint64_t)curr + WIN_INIT) {
|
||||
/* High water mark at or above current data, but below current data
|
||||
* plus WIN_INIT -- zero out to current data plus WIN_INIT, or up
|
||||
* to end of window, whichever is less.
|
||||
*/
|
||||
init = (uint64_t)curr + WIN_INIT - s->high_water;
|
||||
if (init > s->window_size - s->high_water)
|
||||
init = s->window_size - s->high_water;
|
||||
memset(s->window + s->high_water, 0, init);
|
||||
s->high_water += init;
|
||||
}
|
||||
}
|
||||
|
||||
Assert((uint64_t)s->strstart <= s->window_size - MIN_LOOKAHEAD,
|
||||
"not enough room for search");
|
||||
}
|
608
third_party/zlib/infback.c
vendored
Normal file
608
third_party/zlib/infback.c
vendored
Normal file
|
@ -0,0 +1,608 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 1995-2016 Jean-loup Gailly and Mark Adler │
|
||||
│ Use of this source code is governed by the BSD-style licenses that can │
|
||||
│ be found in the third_party/zlib/LICENSE file. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/str/str.h"
|
||||
#include "third_party/zlib/inffast.h"
|
||||
#include "third_party/zlib/inflate.h"
|
||||
#include "third_party/zlib/inftrees.h"
|
||||
#include "third_party/zlib/internal.h"
|
||||
#include "third_party/zlib/zutil.h"
|
||||
|
||||
asm(".ident\t\"\\n\\n\
|
||||
zlib (zlib License)\\n\
|
||||
Copyright 1995-2017 Jean-loup Gailly and Mark Adler\"");
|
||||
asm(".include \"libc/disclaimer.inc\"");
|
||||
|
||||
/*
|
||||
This code is largely copied from inflate.c. Normally either infback.o or
|
||||
inflate.o would be linked into an application--not both. The interface
|
||||
with inffast.c is retained so that optimized assembler-coded versions of
|
||||
inflate_fast() can be used with either inflate.c or infback.c.
|
||||
*/
|
||||
|
||||
/**
|
||||
* strm provides memory allocation functions in zalloc and zfree, or
|
||||
* Z_NULL to use the library memory allocation functions.
|
||||
*
|
||||
* windowBits is in the range 8..15, and window is a user-supplied
|
||||
* window and output buffer that is 2**windowBits bytes.
|
||||
*/
|
||||
int inflateBackInit(z_streamp strm, int windowBits, unsigned char *window) {
|
||||
struct InflateState *state;
|
||||
if (strm == Z_NULL || window == Z_NULL || windowBits < 8 || windowBits > 15) {
|
||||
return Z_STREAM_ERROR;
|
||||
}
|
||||
strm->msg = Z_NULL; /* in case we return an error */
|
||||
if (strm->zalloc == (alloc_func)0) {
|
||||
strm->zalloc = zcalloc;
|
||||
strm->opaque = (voidpf)0;
|
||||
}
|
||||
if (strm->zfree == (free_func)0) {
|
||||
strm->zfree = zcfree;
|
||||
}
|
||||
state = (struct InflateState *)ZALLOC(strm, 1, sizeof(struct InflateState));
|
||||
if (state == Z_NULL) return Z_MEM_ERROR;
|
||||
Tracev((stderr, "inflate: allocated\n"));
|
||||
strm->state = (struct DeflateState *)state;
|
||||
state->dmax = 32768U;
|
||||
state->wbits = (uInt)windowBits;
|
||||
state->wsize = 1U << windowBits;
|
||||
state->window = window;
|
||||
state->wnext = 0;
|
||||
state->whave = 0;
|
||||
return Z_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns state with length and distance decoding tables and index
|
||||
* sizes set to fixed code decoding. Normally this returns fixed tables
|
||||
* from inffixed.h. If BUILDFIXED is defined, then instead this routine
|
||||
* builds the tables the first time it's called, and returns those
|
||||
* tables the first time and thereafter. This reduces the size of the
|
||||
* code by about 2K bytes, in exchange for a little execution time.
|
||||
* However, BUILDFIXED should not be used for threaded applications,
|
||||
* since the rewriting of the tables and virgin may not be thread-safe.
|
||||
*/
|
||||
static void fixedtables(struct InflateState *state) {
|
||||
#ifdef BUILDFIXED
|
||||
static int virgin = 1;
|
||||
static code *lenfix, *distfix;
|
||||
static code fixed[544];
|
||||
/* build fixed huffman tables if first call (may not be thread safe) */
|
||||
if (virgin) {
|
||||
unsigned sym, bits;
|
||||
static code *next;
|
||||
/* literal/length table */
|
||||
sym = 0;
|
||||
while (sym < 144) state->lens[sym++] = 8;
|
||||
while (sym < 256) state->lens[sym++] = 9;
|
||||
while (sym < 280) state->lens[sym++] = 7;
|
||||
while (sym < 288) state->lens[sym++] = 8;
|
||||
next = fixed;
|
||||
lenfix = next;
|
||||
bits = 9;
|
||||
inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work);
|
||||
/* distance table */
|
||||
sym = 0;
|
||||
while (sym < 32) state->lens[sym++] = 5;
|
||||
distfix = next;
|
||||
bits = 5;
|
||||
inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work);
|
||||
/* do this just once */
|
||||
virgin = 0;
|
||||
}
|
||||
state->lencode = lenfix;
|
||||
state->distcode = distfix;
|
||||
#else /* !BUILDFIXED */
|
||||
state->lencode = kZlibLenfix;
|
||||
state->distcode = kZlibDistfix;
|
||||
#endif /* BUILDFIXED */
|
||||
state->lenbits = 9;
|
||||
state->distbits = 5;
|
||||
}
|
||||
|
||||
/* Macros for inflateBack(): */
|
||||
|
||||
/* Load returned state from inflate_fast() */
|
||||
#define LOAD() \
|
||||
do { \
|
||||
put = strm->next_out; \
|
||||
left = strm->avail_out; \
|
||||
next = strm->next_in; \
|
||||
have = strm->avail_in; \
|
||||
hold = state->hold; \
|
||||
bits = state->bits; \
|
||||
} while (0)
|
||||
|
||||
/* Set state from registers for inflate_fast() */
|
||||
#define RESTORE() \
|
||||
do { \
|
||||
strm->next_out = put; \
|
||||
strm->avail_out = left; \
|
||||
strm->next_in = next; \
|
||||
strm->avail_in = have; \
|
||||
state->hold = hold; \
|
||||
state->bits = bits; \
|
||||
} while (0)
|
||||
|
||||
/* Clear the input bit accumulator */
|
||||
#define INITBITS() \
|
||||
do { \
|
||||
hold = 0; \
|
||||
bits = 0; \
|
||||
} while (0)
|
||||
|
||||
/* Assure that some input is available. If input is requested, but denied,
|
||||
then return a Z_BUF_ERROR from inflateBack(). */
|
||||
#define PULL() \
|
||||
do { \
|
||||
if (have == 0) { \
|
||||
have = in(in_desc, &next); \
|
||||
if (have == 0) { \
|
||||
next = Z_NULL; \
|
||||
ret = Z_BUF_ERROR; \
|
||||
goto inf_leave; \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/* Get a byte of input into the bit accumulator, or return from inflateBack()
|
||||
with an error if there is no input available. */
|
||||
#define PULLBYTE() \
|
||||
do { \
|
||||
PULL(); \
|
||||
have--; \
|
||||
hold += (unsigned long)(*next++) << bits; \
|
||||
bits += 8; \
|
||||
} while (0)
|
||||
|
||||
/* Assure that there are at least n bits in the bit accumulator. If there is
|
||||
not enough available input to do that, then return from inflateBack() with
|
||||
an error. */
|
||||
#define NEEDBITS(n) \
|
||||
do { \
|
||||
while (bits < (unsigned)(n)) PULLBYTE(); \
|
||||
} while (0)
|
||||
|
||||
/* Return the low n bits of the bit accumulator (n < 16) */
|
||||
#define BITS(n) ((unsigned)hold & ((1U << (n)) - 1))
|
||||
|
||||
/* Remove n bits from the bit accumulator */
|
||||
#define DROPBITS(n) \
|
||||
do { \
|
||||
hold >>= (n); \
|
||||
bits -= (unsigned)(n); \
|
||||
} while (0)
|
||||
|
||||
/* Remove zero to seven bits as needed to go to a byte boundary */
|
||||
#define BYTEBITS() \
|
||||
do { \
|
||||
hold >>= bits & 7; \
|
||||
bits -= bits & 7; \
|
||||
} while (0)
|
||||
|
||||
/* Assure that some output space is available, by writing out the window
|
||||
if it's full. If the write fails, return from inflateBack() with a
|
||||
Z_BUF_ERROR. */
|
||||
#define ROOM() \
|
||||
do { \
|
||||
if (left == 0) { \
|
||||
put = state->window; \
|
||||
left = state->wsize; \
|
||||
state->whave = left; \
|
||||
if (out(out_desc, put, left)) { \
|
||||
ret = Z_BUF_ERROR; \
|
||||
goto inf_leave; \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* strm provides the memory allocation functions and window buffer on
|
||||
* input, and provides information on the unused input on return. For
|
||||
* Z_DATA_ERROR returns, strm will also provide an error message.
|
||||
*
|
||||
* in() and out() are the call-back input and output functions. When
|
||||
* inflateBack() needs more input, it calls in(). When inflateBack() has
|
||||
* filled the window with output, or when it completes with data in the
|
||||
* window, it calls out() to write out the data. The application must
|
||||
* not change the provided input until in() is called again or
|
||||
* inflateBack() returns. The application must not change the
|
||||
* window/output buffer until inflateBack() returns.
|
||||
*
|
||||
* in() and out() are called with a descriptor parameter provided in the
|
||||
* inflateBack() call. This parameter can be a structure that provides
|
||||
* the information required to do the read or write, as well as
|
||||
* accumulated information on the input and output such as totals and
|
||||
* check values.
|
||||
*
|
||||
* in() should return zero on failure. out() should return non-zero on
|
||||
* failure. If either in() or out() fails, than inflateBack() returns a
|
||||
* Z_BUF_ERROR. strm->next_in can be checked for Z_NULL to see whether
|
||||
* it was in() or out() that caused in the error. Otherwise,
|
||||
* inflateBack() returns Z_STREAM_END on success, Z_DATA_ERROR for an
|
||||
* deflate format error, or Z_MEM_ERROR if it could not allocate memory
|
||||
* for the state. inflateBack() can also return Z_STREAM_ERROR if the
|
||||
* input parameters are not correct, i.e. strm is Z_NULL or the state
|
||||
* was not initialized.
|
||||
*/
|
||||
int inflateBack(z_streamp strm, in_func in, void *in_desc, out_func out,
|
||||
void *out_desc) {
|
||||
struct InflateState *state;
|
||||
const unsigned char *next; /* next input */
|
||||
unsigned char *put; /* next output */
|
||||
unsigned have, left; /* available input and output */
|
||||
unsigned long hold; /* bit buffer */
|
||||
unsigned bits; /* bits in bit buffer */
|
||||
unsigned copy; /* number of stored or match bytes to copy */
|
||||
unsigned char *from; /* where to copy match bytes from */
|
||||
struct zcode here; /* current decoding table entry */
|
||||
struct zcode last; /* parent table entry */
|
||||
unsigned len; /* length to copy for repeats, bits to drop */
|
||||
int ret; /* return code */
|
||||
static const unsigned short order[19] = /* permutation of code lengths */
|
||||
{16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
|
||||
|
||||
/* Check that the strm exists and that the state was initialized */
|
||||
if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
|
||||
state = (struct InflateState *)strm->state;
|
||||
|
||||
/* Reset the state */
|
||||
strm->msg = Z_NULL;
|
||||
state->mode = TYPE;
|
||||
state->last = 0;
|
||||
state->whave = 0;
|
||||
next = strm->next_in;
|
||||
have = next != Z_NULL ? strm->avail_in : 0;
|
||||
hold = 0;
|
||||
bits = 0;
|
||||
put = state->window;
|
||||
left = state->wsize;
|
||||
|
||||
/* Inflate until end of block marked as last */
|
||||
for (;;) switch (state->mode) {
|
||||
case TYPE:
|
||||
/* determine and dispatch block type */
|
||||
if (state->last) {
|
||||
BYTEBITS();
|
||||
state->mode = DONE;
|
||||
break;
|
||||
}
|
||||
NEEDBITS(3);
|
||||
state->last = BITS(1);
|
||||
DROPBITS(1);
|
||||
switch (BITS(2)) {
|
||||
case 0: /* stored block */
|
||||
Tracev((stderr, "inflate: stored block%s\n",
|
||||
state->last ? " (last)" : ""));
|
||||
state->mode = STORED;
|
||||
break;
|
||||
case 1: /* fixed block */
|
||||
fixedtables(state);
|
||||
Tracev((stderr, "inflate: fixed codes block%s\n",
|
||||
state->last ? " (last)" : ""));
|
||||
state->mode = LEN; /* decode codes */
|
||||
break;
|
||||
case 2: /* dynamic block */
|
||||
Tracev((stderr, "inflate: dynamic codes block%s\n",
|
||||
state->last ? " (last)" : ""));
|
||||
state->mode = TABLE;
|
||||
break;
|
||||
case 3:
|
||||
strm->msg = (char *)"invalid block type";
|
||||
state->mode = BAD;
|
||||
}
|
||||
DROPBITS(2);
|
||||
break;
|
||||
|
||||
case STORED:
|
||||
/* get and verify stored block length */
|
||||
BYTEBITS(); /* go to byte boundary */
|
||||
NEEDBITS(32);
|
||||
if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) {
|
||||
strm->msg = (char *)"invalid stored block lengths";
|
||||
state->mode = BAD;
|
||||
break;
|
||||
}
|
||||
state->length = (unsigned)hold & 0xffff;
|
||||
Tracev((stderr, "inflate: stored length %u\n", state->length));
|
||||
INITBITS();
|
||||
|
||||
/* copy stored block from input to output */
|
||||
while (state->length != 0) {
|
||||
copy = state->length;
|
||||
PULL();
|
||||
ROOM();
|
||||
if (copy > have) copy = have;
|
||||
if (copy > left) copy = left;
|
||||
memcpy(put, next, copy);
|
||||
have -= copy;
|
||||
next += copy;
|
||||
left -= copy;
|
||||
put += copy;
|
||||
state->length -= copy;
|
||||
}
|
||||
Tracev((stderr, "inflate: stored end\n"));
|
||||
state->mode = TYPE;
|
||||
break;
|
||||
|
||||
case TABLE:
|
||||
/* get dynamic table entries descriptor */
|
||||
NEEDBITS(14);
|
||||
state->nlen = BITS(5) + 257;
|
||||
DROPBITS(5);
|
||||
state->ndist = BITS(5) + 1;
|
||||
DROPBITS(5);
|
||||
state->ncode = BITS(4) + 4;
|
||||
DROPBITS(4);
|
||||
#ifndef PKZIP_BUG_WORKAROUND
|
||||
if (state->nlen > 286 || state->ndist > 30) {
|
||||
strm->msg = (char *)"too many length or distance symbols";
|
||||
state->mode = BAD;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
Tracev((stderr, "inflate: table sizes ok\n"));
|
||||
|
||||
/* get code length code lengths (not a typo) */
|
||||
state->have = 0;
|
||||
while (state->have < state->ncode) {
|
||||
NEEDBITS(3);
|
||||
state->lens[order[state->have++]] = (unsigned short)BITS(3);
|
||||
DROPBITS(3);
|
||||
}
|
||||
while (state->have < 19) state->lens[order[state->have++]] = 0;
|
||||
state->next = state->codes;
|
||||
state->lencode = (const struct zcode *)(state->next);
|
||||
state->lenbits = 7;
|
||||
ret = inflate_table(CODES, state->lens, 19, &(state->next),
|
||||
&(state->lenbits), state->work);
|
||||
if (ret) {
|
||||
strm->msg = (char *)"invalid code lengths set";
|
||||
state->mode = BAD;
|
||||
break;
|
||||
}
|
||||
Tracev((stderr, "inflate: code lengths ok\n"));
|
||||
|
||||
/* get length and distance code code lengths */
|
||||
state->have = 0;
|
||||
while (state->have < state->nlen + state->ndist) {
|
||||
for (;;) {
|
||||
here = state->lencode[BITS(state->lenbits)];
|
||||
if ((unsigned)(here.bits) <= bits) break;
|
||||
PULLBYTE();
|
||||
}
|
||||
if (here.val < 16) {
|
||||
DROPBITS(here.bits);
|
||||
state->lens[state->have++] = here.val;
|
||||
} else {
|
||||
if (here.val == 16) {
|
||||
NEEDBITS(here.bits + 2);
|
||||
DROPBITS(here.bits);
|
||||
if (state->have == 0) {
|
||||
strm->msg = (char *)"invalid bit length repeat";
|
||||
state->mode = BAD;
|
||||
break;
|
||||
}
|
||||
len = (unsigned)(state->lens[state->have - 1]);
|
||||
copy = 3 + BITS(2);
|
||||
DROPBITS(2);
|
||||
} else if (here.val == 17) {
|
||||
NEEDBITS(here.bits + 3);
|
||||
DROPBITS(here.bits);
|
||||
len = 0;
|
||||
copy = 3 + BITS(3);
|
||||
DROPBITS(3);
|
||||
} else {
|
||||
NEEDBITS(here.bits + 7);
|
||||
DROPBITS(here.bits);
|
||||
len = 0;
|
||||
copy = 11 + BITS(7);
|
||||
DROPBITS(7);
|
||||
}
|
||||
if (state->have + copy > state->nlen + state->ndist) {
|
||||
strm->msg = (char *)"invalid bit length repeat";
|
||||
state->mode = BAD;
|
||||
break;
|
||||
}
|
||||
while (copy--) state->lens[state->have++] = (unsigned short)len;
|
||||
}
|
||||
}
|
||||
|
||||
/* handle error breaks in while */
|
||||
if (state->mode == BAD) break;
|
||||
|
||||
/* check for end-of-block code (better have one) */
|
||||
if (state->lens[256] == 0) {
|
||||
strm->msg = (char *)"invalid code -- missing end-of-block";
|
||||
state->mode = BAD;
|
||||
break;
|
||||
}
|
||||
|
||||
/* build code tables -- note: do not change the lenbits or distbits
|
||||
values here (9 and 6) without reading the comments in inftrees.h
|
||||
concerning the ENOUGH constants, which depend on those values */
|
||||
state->next = state->codes;
|
||||
state->lencode = (const struct zcode *)(state->next);
|
||||
state->lenbits = 9;
|
||||
ret = inflate_table(LENS, state->lens, state->nlen, &(state->next),
|
||||
&(state->lenbits), state->work);
|
||||
if (ret) {
|
||||
strm->msg = (char *)"invalid literal/lengths set";
|
||||
state->mode = BAD;
|
||||
break;
|
||||
}
|
||||
state->distcode = (const struct zcode *)(state->next);
|
||||
state->distbits = 6;
|
||||
ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist,
|
||||
&(state->next), &(state->distbits), state->work);
|
||||
if (ret) {
|
||||
strm->msg = (char *)"invalid distances set";
|
||||
state->mode = BAD;
|
||||
break;
|
||||
}
|
||||
Tracev((stderr, "inflate: codes ok\n"));
|
||||
state->mode = LEN;
|
||||
|
||||
case LEN:
|
||||
/* use inflate_fast() if we have enough input and output */
|
||||
if (have >= INFLATE_FAST_MIN_INPUT && left >= INFLATE_FAST_MIN_OUTPUT) {
|
||||
RESTORE();
|
||||
if (state->whave < state->wsize) state->whave = state->wsize - left;
|
||||
inflate_fast(strm, state->wsize);
|
||||
LOAD();
|
||||
break;
|
||||
}
|
||||
|
||||
/* get a literal, length, or end-of-block code */
|
||||
for (;;) {
|
||||
here = state->lencode[BITS(state->lenbits)];
|
||||
if ((unsigned)(here.bits) <= bits) break;
|
||||
PULLBYTE();
|
||||
}
|
||||
if (here.op && (here.op & 0xf0) == 0) {
|
||||
last = here;
|
||||
for (;;) {
|
||||
here = state->lencode[last.val +
|
||||
(BITS(last.bits + last.op) >> last.bits)];
|
||||
if ((unsigned)(last.bits + here.bits) <= bits) break;
|
||||
PULLBYTE();
|
||||
}
|
||||
DROPBITS(last.bits);
|
||||
}
|
||||
DROPBITS(here.bits);
|
||||
state->length = (unsigned)here.val;
|
||||
|
||||
/* process literal */
|
||||
if (here.op == 0) {
|
||||
Tracevv((stderr,
|
||||
here.val >= 0x20 && here.val < 0x7f
|
||||
? "inflate: literal '%c'\n"
|
||||
: "inflate: literal 0x%02x\n",
|
||||
here.val));
|
||||
ROOM();
|
||||
*put++ = (unsigned char)(state->length);
|
||||
left--;
|
||||
state->mode = LEN;
|
||||
break;
|
||||
}
|
||||
|
||||
/* process end of block */
|
||||
if (here.op & 32) {
|
||||
Tracevv((stderr, "inflate: end of block\n"));
|
||||
state->mode = TYPE;
|
||||
break;
|
||||
}
|
||||
|
||||
/* invalid code */
|
||||
if (here.op & 64) {
|
||||
strm->msg = (char *)"invalid literal/length code";
|
||||
state->mode = BAD;
|
||||
break;
|
||||
}
|
||||
|
||||
/* length code -- get extra bits, if any */
|
||||
state->extra = (unsigned)(here.op) & 15;
|
||||
if (state->extra != 0) {
|
||||
NEEDBITS(state->extra);
|
||||
state->length += BITS(state->extra);
|
||||
DROPBITS(state->extra);
|
||||
}
|
||||
Tracevv((stderr, "inflate: length %u\n", state->length));
|
||||
|
||||
/* get distance code */
|
||||
for (;;) {
|
||||
here = state->distcode[BITS(state->distbits)];
|
||||
if ((unsigned)(here.bits) <= bits) break;
|
||||
PULLBYTE();
|
||||
}
|
||||
if ((here.op & 0xf0) == 0) {
|
||||
last = here;
|
||||
for (;;) {
|
||||
here = state->distcode[last.val +
|
||||
(BITS(last.bits + last.op) >> last.bits)];
|
||||
if ((unsigned)(last.bits + here.bits) <= bits) break;
|
||||
PULLBYTE();
|
||||
}
|
||||
DROPBITS(last.bits);
|
||||
}
|
||||
DROPBITS(here.bits);
|
||||
if (here.op & 64) {
|
||||
strm->msg = (char *)"invalid distance code";
|
||||
state->mode = BAD;
|
||||
break;
|
||||
}
|
||||
state->offset = (unsigned)here.val;
|
||||
|
||||
/* get distance extra bits, if any */
|
||||
state->extra = (unsigned)(here.op) & 15;
|
||||
if (state->extra != 0) {
|
||||
NEEDBITS(state->extra);
|
||||
state->offset += BITS(state->extra);
|
||||
DROPBITS(state->extra);
|
||||
}
|
||||
if (state->offset >
|
||||
state->wsize - (state->whave < state->wsize ? left : 0)) {
|
||||
strm->msg = (char *)"invalid distance too far back";
|
||||
state->mode = BAD;
|
||||
break;
|
||||
}
|
||||
Tracevv((stderr, "inflate: distance %u\n", state->offset));
|
||||
|
||||
/* copy match from window to output */
|
||||
do {
|
||||
ROOM();
|
||||
copy = state->wsize - state->offset;
|
||||
if (copy < left) {
|
||||
from = put + copy;
|
||||
copy = left - copy;
|
||||
} else {
|
||||
from = put - state->offset;
|
||||
copy = left;
|
||||
}
|
||||
if (copy > state->length) copy = state->length;
|
||||
state->length -= copy;
|
||||
left -= copy;
|
||||
do {
|
||||
*put++ = *from++;
|
||||
} while (--copy);
|
||||
} while (state->length != 0);
|
||||
break;
|
||||
|
||||
case DONE:
|
||||
/* inflate stream terminated properly -- write leftover output */
|
||||
ret = Z_STREAM_END;
|
||||
if (left < state->wsize) {
|
||||
if (out(out_desc, state->window, state->wsize - left))
|
||||
ret = Z_BUF_ERROR;
|
||||
}
|
||||
goto inf_leave;
|
||||
|
||||
case BAD:
|
||||
ret = Z_DATA_ERROR;
|
||||
goto inf_leave;
|
||||
|
||||
default: /* can't happen, but makes compilers happy */
|
||||
ret = Z_STREAM_ERROR;
|
||||
goto inf_leave;
|
||||
}
|
||||
|
||||
/* Return unused input */
|
||||
inf_leave:
|
||||
strm->next_in = next;
|
||||
strm->avail_in = have;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int inflateBackEnd(z_streamp strm) {
|
||||
if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0)
|
||||
return Z_STREAM_ERROR;
|
||||
ZFREE(strm, strm->state);
|
||||
strm->state = Z_NULL;
|
||||
Tracev((stderr, "inflate: end\n"));
|
||||
return Z_OK;
|
||||
}
|
308
third_party/zlib/inffast.c
vendored
Normal file
308
third_party/zlib/inffast.c
vendored
Normal file
|
@ -0,0 +1,308 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=4 sts=4 sw=4 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 1995-2017 Mark Adler │
|
||||
│ Use of this source code is governed by the BSD-style licenses that can │
|
||||
│ be found in the third_party/zlib/LICENSE file. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "third_party/zlib/inffast.h"
|
||||
#include "third_party/zlib/inflate.h"
|
||||
#include "third_party/zlib/inftrees.h"
|
||||
#include "third_party/zlib/zutil.h"
|
||||
|
||||
asm(".ident\t\"\\n\\n\
|
||||
zlib (zlib License)\\n\
|
||||
Copyright 1995-2017 Jean-loup Gailly and Mark Adler\"");
|
||||
asm(".include \"libc/disclaimer.inc\"");
|
||||
|
||||
/**
|
||||
* Decodes literal, length, and distance codes and write out the
|
||||
* resulting literal and match bytes until either not enough input or
|
||||
* output is available, an end-of-block is encountered, or a data error
|
||||
* is encountered. When large enough input and output buffers are
|
||||
* supplied to inflate(), for example, a 16K input buffer and a 64K
|
||||
* output buffer, more than 95% of the inflate() execution time is spent
|
||||
* in this routine.
|
||||
*
|
||||
* Entry assumptions:
|
||||
*
|
||||
* state->mode == LEN
|
||||
* strm->avail_in >= INFLATE_FAST_MIN_INPUT (6 bytes)
|
||||
* strm->avail_out >= INFLATE_FAST_MIN_OUTPUT (258 bytes)
|
||||
* start >= strm->avail_out
|
||||
* state->bits < 8
|
||||
*
|
||||
* On return, state->mode is one of:
|
||||
*
|
||||
* LEN -- ran out of enough output space or enough available input
|
||||
* TYPE -- reached end of block code, inflate() to interpret next block
|
||||
* BAD -- error in block data
|
||||
*
|
||||
* Some notes:
|
||||
*
|
||||
* INFLATE_FAST_MIN_INPUT: 6 bytes
|
||||
*
|
||||
* - The maximum input bits used by a length/distance pair is 15 bits
|
||||
* for the length code, 5 bits for the length extra, 15 bits for the
|
||||
* distance code, and 13 bits for the distance extra. This totals 48
|
||||
* bits, or six bytes. Therefore if strm->avail_in >= 6, then there
|
||||
* is enough input to avoid checking for available input while
|
||||
* decoding.
|
||||
*
|
||||
* INFLATE_FAST_MIN_OUTPUT: 258 bytes
|
||||
*
|
||||
* - The maximum bytes that a single length/distance pair can output is
|
||||
* 258 bytes, which is the maximum length that can be coded.
|
||||
* inflate_fast() requires strm->avail_out >= 258 for each loop to
|
||||
* avoid checking for available output space while decoding.
|
||||
*
|
||||
* @param start inflate() starting value for strm->avail_out
|
||||
*/
|
||||
void inflate_fast(z_streamp strm, unsigned start) {
|
||||
struct InflateState *state;
|
||||
const unsigned char *in; /* local strm->next_in */
|
||||
const unsigned char *last; /* have enough input while in < last */
|
||||
unsigned char *out; /* local strm->next_out */
|
||||
unsigned char *beg; /* inflate()'s initial strm->next_out */
|
||||
unsigned char *end; /* while out < end, enough space available */
|
||||
#ifdef INFLATE_STRICT
|
||||
unsigned dmax; /* maximum distance from zlib header */
|
||||
#endif
|
||||
unsigned wsize; /* window size or zero if not using window */
|
||||
unsigned whave; /* valid bytes in the window */
|
||||
unsigned wnext; /* window write index */
|
||||
unsigned char *window; /* allocated sliding window, if wsize != 0 */
|
||||
unsigned long hold; /* local strm->hold */
|
||||
unsigned bits; /* local strm->bits */
|
||||
const struct zcode *lcode; /* local strm->lencode */
|
||||
const struct zcode *dcode; /* local strm->distcode */
|
||||
unsigned lmask; /* mask for first level of length codes */
|
||||
unsigned dmask; /* mask for first level of distance codes */
|
||||
struct zcode here; /* retrieved table entry */
|
||||
unsigned op; /* code bits, operation, extra bits, or */
|
||||
/* window position, window bytes to copy */
|
||||
unsigned len; /* match length, unused bytes */
|
||||
unsigned dist; /* match distance */
|
||||
unsigned char *from; /* where to copy match from */
|
||||
|
||||
/* copy state to local variables */
|
||||
state = (struct InflateState *)strm->state;
|
||||
in = strm->next_in;
|
||||
last = in + (strm->avail_in - (INFLATE_FAST_MIN_INPUT - 1));
|
||||
out = strm->next_out;
|
||||
beg = out - (start - strm->avail_out);
|
||||
end = out + (strm->avail_out - (INFLATE_FAST_MIN_OUTPUT - 1));
|
||||
#ifdef INFLATE_STRICT
|
||||
dmax = state->dmax;
|
||||
#endif
|
||||
wsize = state->wsize;
|
||||
whave = state->whave;
|
||||
wnext = state->wnext;
|
||||
window = state->window;
|
||||
hold = state->hold;
|
||||
bits = state->bits;
|
||||
lcode = state->lencode;
|
||||
dcode = state->distcode;
|
||||
lmask = (1U << state->lenbits) - 1;
|
||||
dmask = (1U << state->distbits) - 1;
|
||||
|
||||
/* decode literals and length/distances until end-of-block or not enough
|
||||
input data or output space */
|
||||
do {
|
||||
if (bits < 15) {
|
||||
hold += (unsigned long)(*in++) << bits;
|
||||
bits += 8;
|
||||
hold += (unsigned long)(*in++) << bits;
|
||||
bits += 8;
|
||||
}
|
||||
here = lcode[hold & lmask];
|
||||
dolen:
|
||||
op = (unsigned)(here.bits);
|
||||
hold >>= op;
|
||||
bits -= op;
|
||||
op = (unsigned)(here.op);
|
||||
if (op == 0) { /* literal */
|
||||
Tracevv((stderr,
|
||||
here.val >= 0x20 && here.val < 0x7f
|
||||
? "inflate: literal '%c'\n"
|
||||
: "inflate: literal 0x%02x\n",
|
||||
here.val));
|
||||
*out++ = (unsigned char)(here.val);
|
||||
} else if (op & 16) { /* length base */
|
||||
len = (unsigned)(here.val);
|
||||
op &= 15; /* number of extra bits */
|
||||
if (op) {
|
||||
if (bits < op) {
|
||||
hold += (unsigned long)(*in++) << bits;
|
||||
bits += 8;
|
||||
}
|
||||
len += (unsigned)hold & ((1U << op) - 1);
|
||||
hold >>= op;
|
||||
bits -= op;
|
||||
}
|
||||
Tracevv((stderr, "inflate: length %u\n", len));
|
||||
if (bits < 15) {
|
||||
hold += (unsigned long)(*in++) << bits;
|
||||
bits += 8;
|
||||
hold += (unsigned long)(*in++) << bits;
|
||||
bits += 8;
|
||||
}
|
||||
here = dcode[hold & dmask];
|
||||
dodist:
|
||||
op = (unsigned)(here.bits);
|
||||
hold >>= op;
|
||||
bits -= op;
|
||||
op = (unsigned)(here.op);
|
||||
if (op & 16) { /* distance base */
|
||||
dist = (unsigned)(here.val);
|
||||
op &= 15; /* number of extra bits */
|
||||
if (bits < op) {
|
||||
hold += (unsigned long)(*in++) << bits;
|
||||
bits += 8;
|
||||
if (bits < op) {
|
||||
hold += (unsigned long)(*in++) << bits;
|
||||
bits += 8;
|
||||
}
|
||||
}
|
||||
dist += (unsigned)hold & ((1U << op) - 1);
|
||||
#ifdef INFLATE_STRICT
|
||||
if (dist > dmax) {
|
||||
strm->msg = (char *)"invalid distance too far back";
|
||||
state->mode = BAD;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
hold >>= op;
|
||||
bits -= op;
|
||||
Tracevv((stderr, "inflate: distance %u\n", dist));
|
||||
op = (unsigned)(out - beg); /* max distance in output */
|
||||
if (dist > op) { /* see if copy from window */
|
||||
op = dist - op; /* distance back in window */
|
||||
if (op > whave) {
|
||||
if (state->sane) {
|
||||
strm->msg = (char *)"invalid distance too far back";
|
||||
state->mode = BAD;
|
||||
break;
|
||||
}
|
||||
#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
|
||||
if (len <= op - whave) {
|
||||
do {
|
||||
*out++ = 0;
|
||||
} while (--len);
|
||||
continue;
|
||||
}
|
||||
len -= op - whave;
|
||||
do {
|
||||
*out++ = 0;
|
||||
} while (--op > whave);
|
||||
if (op == 0) {
|
||||
from = out - dist;
|
||||
do {
|
||||
*out++ = *from++;
|
||||
} while (--len);
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
from = window;
|
||||
if (wnext == 0) { /* very common case */
|
||||
from += wsize - op;
|
||||
if (op < len) { /* some from window */
|
||||
len -= op;
|
||||
do {
|
||||
*out++ = *from++;
|
||||
} while (--op);
|
||||
from = out - dist; /* rest from output */
|
||||
}
|
||||
} else if (wnext < op) { /* wrap around window */
|
||||
from += wsize + wnext - op;
|
||||
op -= wnext;
|
||||
if (op < len) { /* some from end of window */
|
||||
len -= op;
|
||||
do {
|
||||
*out++ = *from++;
|
||||
} while (--op);
|
||||
from = window;
|
||||
if (wnext < len) { /* some from start of window */
|
||||
op = wnext;
|
||||
len -= op;
|
||||
do {
|
||||
*out++ = *from++;
|
||||
} while (--op);
|
||||
from = out - dist; /* rest from output */
|
||||
}
|
||||
}
|
||||
} else { /* contiguous in window */
|
||||
from += wnext - op;
|
||||
if (op < len) { /* some from window */
|
||||
len -= op;
|
||||
do {
|
||||
*out++ = *from++;
|
||||
} while (--op);
|
||||
from = out - dist; /* rest from output */
|
||||
}
|
||||
}
|
||||
while (len > 2) {
|
||||
*out++ = *from++;
|
||||
*out++ = *from++;
|
||||
*out++ = *from++;
|
||||
len -= 3;
|
||||
}
|
||||
if (len) {
|
||||
*out++ = *from++;
|
||||
if (len > 1) *out++ = *from++;
|
||||
}
|
||||
} else {
|
||||
from = out - dist; /* copy direct from output */
|
||||
do { /* minimum length is three */
|
||||
*out++ = *from++;
|
||||
*out++ = *from++;
|
||||
*out++ = *from++;
|
||||
len -= 3;
|
||||
} while (len > 2);
|
||||
if (len) {
|
||||
*out++ = *from++;
|
||||
if (len > 1) *out++ = *from++;
|
||||
}
|
||||
}
|
||||
} else if ((op & 64) == 0) { /* 2nd level distance code */
|
||||
here = dcode[here.val + (hold & ((1U << op) - 1))];
|
||||
goto dodist;
|
||||
} else {
|
||||
strm->msg = (char *)"invalid distance code";
|
||||
state->mode = BAD;
|
||||
break;
|
||||
}
|
||||
} else if ((op & 64) == 0) { /* 2nd level length code */
|
||||
here = lcode[here.val + (hold & ((1U << op) - 1))];
|
||||
goto dolen;
|
||||
} else if (op & 32) { /* end-of-block */
|
||||
Tracevv((stderr, "inflate: end of block\n"));
|
||||
state->mode = TYPE;
|
||||
break;
|
||||
} else {
|
||||
strm->msg = (char *)"invalid literal/length code";
|
||||
state->mode = BAD;
|
||||
break;
|
||||
}
|
||||
} while (in < last && out < end);
|
||||
|
||||
/* return unused bytes (on entry, bits < 8, so in won't go too far back) */
|
||||
len = bits >> 3;
|
||||
in -= len;
|
||||
bits -= len << 3;
|
||||
hold &= (1U << bits) - 1;
|
||||
|
||||
/* update state and return */
|
||||
strm->next_in = in;
|
||||
strm->next_out = out;
|
||||
strm->avail_in =
|
||||
(unsigned)(in < last ? (INFLATE_FAST_MIN_INPUT - 1) + (last - in)
|
||||
: (INFLATE_FAST_MIN_INPUT - 1) - (in - last));
|
||||
strm->avail_out =
|
||||
(unsigned)(out < end ? (INFLATE_FAST_MIN_OUTPUT - 1) + (end - out)
|
||||
: (INFLATE_FAST_MIN_OUTPUT - 1) - (out - end));
|
||||
state->hold = hold;
|
||||
state->bits = bits;
|
||||
return;
|
||||
}
|
28
third_party/zlib/inffast.h
vendored
Normal file
28
third_party/zlib/inffast.h
vendored
Normal file
|
@ -0,0 +1,28 @@
|
|||
#ifndef COSMOPOLITAN_THIRD_PARTY_ZLIB_INFFAST_H_
|
||||
#define COSMOPOLITAN_THIRD_PARTY_ZLIB_INFFAST_H_
|
||||
#include "third_party/zlib/inffast.h"
|
||||
#include "third_party/zlib/zlib.h"
|
||||
|
||||
/* INFLATE_FAST_MIN_INPUT: the minimum number of input bytes needed so that
|
||||
we can safely call inflate_fast() with only one up-front bounds check. One
|
||||
length/distance code pair (15 bits for the length code, 5 bits for length
|
||||
extra, 15 bits for the distance code, 13 bits for distance extra) requires
|
||||
reading up to 48 input bits (6 bytes).
|
||||
*/
|
||||
#define INFLATE_FAST_MIN_INPUT 8
|
||||
|
||||
/* INFLATE_FAST_MIN_OUTPUT: the minimum number of output bytes needed so that
|
||||
we can safely call inflate_fast() with only one up-front bounds check. One
|
||||
length/distance code pair can output up to 258 bytes, which is the maximum
|
||||
length that can be coded.
|
||||
*/
|
||||
#define INFLATE_FAST_MIN_OUTPUT 258
|
||||
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
void inflate_fast(z_streamp strm, unsigned start) hidden;
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_THIRD_PARTY_ZLIB_INFFAST_H_ */
|
315
third_party/zlib/inffastchunk.c
vendored
Normal file
315
third_party/zlib/inffastchunk.c
vendored
Normal file
|
@ -0,0 +1,315 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=4 sts=4 sw=4 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 1995-2017 Mark Adler │
|
||||
│ Use of this source code is governed by the BSD-style licenses that can │
|
||||
│ be found in the third_party/zlib/LICENSE file. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/bits/bits.h"
|
||||
#include "third_party/zlib/chunkcopy.h"
|
||||
#include "third_party/zlib/inffast.h"
|
||||
#include "third_party/zlib/inflate.h"
|
||||
#include "third_party/zlib/inftrees.h"
|
||||
#include "third_party/zlib/zlib.h"
|
||||
#include "third_party/zlib/zutil.h"
|
||||
|
||||
asm(".ident\t\"\\n\\n\
|
||||
zlib (zlib License)\\n\
|
||||
Copyright 1995-2017 Jean-loup Gailly and Mark Adler\"");
|
||||
asm(".include \"libc/disclaimer.inc\"");
|
||||
|
||||
/**
|
||||
* Decodes literal, length, and distance codes and write out the
|
||||
* resulting literal and match bytes until either not enough input or
|
||||
* output is available, an end-of-block is encountered, or a data error
|
||||
* is encountered. When large enough input and output buffers are
|
||||
* supplied to inflate(), for example, a 16K input buffer and a 64K
|
||||
* output buffer, more than 95% of the inflate() execution time is spent
|
||||
* in this routine.
|
||||
*
|
||||
* Entry assumptions:
|
||||
*
|
||||
* state->mode == LEN
|
||||
* strm->avail_in >= INFLATE_FAST_MIN_INPUT (6 or 8 bytes)
|
||||
* strm->avail_out >= INFLATE_FAST_MIN_OUTPUT (258 bytes)
|
||||
* start >= strm->avail_out
|
||||
* state->bits < 8
|
||||
* (state->hold >> state->bits) == 0
|
||||
* strm->next_out[0..strm->avail_out] does not overlap with
|
||||
* strm->next_in[0..strm->avail_in]
|
||||
* strm->state->window is allocated with an additional
|
||||
* CHUNKCOPY_CHUNK_SIZE-1 bytes of padding beyond strm->state->wsize
|
||||
*
|
||||
* On return, state->mode is one of:
|
||||
*
|
||||
* LEN -- ran out of enough output space or enough available input
|
||||
* TYPE -- reached end of block code, inflate() to interpret next block
|
||||
* BAD -- error in block data
|
||||
*
|
||||
* Some notes:
|
||||
*
|
||||
* INFLATE_FAST_MIN_INPUT: 6 or 8 bytes
|
||||
*
|
||||
* - The maximum input bits used by a length/distance pair is 15 bits
|
||||
* for the length code, 5 bits for the length extra, 15 bits for the
|
||||
* distance code, and 13 bits for the distance extra. This totals 48
|
||||
* bits, or six bytes. Therefore if strm->avail_in >= 6, then there
|
||||
* is enough input to avoid checking for available input while
|
||||
* decoding.
|
||||
*
|
||||
* - The wide input data reading option reads 64 input bits at a time.
|
||||
* Thus, if strm->avail_in >= 8, then there is enough input to avoid
|
||||
* checking for available input while decoding. Reading consumes the
|
||||
* input with:
|
||||
*
|
||||
* hold |= READ64LE(in) << bits;
|
||||
* in += 6;
|
||||
* bits += 48;
|
||||
*
|
||||
* reporting 6 bytes of new input because |bits| is 0..15 (2 bytes
|
||||
* rounded up, worst case) and 6 bytes is enough to decode as noted
|
||||
* above. At exit, hold &= (1U << bits) - 1 drops excess input to
|
||||
* keep the invariant:
|
||||
*
|
||||
* (state->hold >> state->bits) == 0
|
||||
*
|
||||
* INFLATE_FAST_MIN_OUTPUT: 258 bytes
|
||||
*
|
||||
* - The maximum bytes that a single length/distance pair can output is
|
||||
* 258 bytes, which is the maximum length that can be coded.
|
||||
* inflate_fast() requires strm->avail_out >= 258 for each loop to
|
||||
* avoid checking for available output space while decoding.
|
||||
*
|
||||
* @param start is inflate() starting value for strm->avail_out
|
||||
*/
|
||||
void inflate_fast_chunk(z_streamp strm, unsigned start) {
|
||||
struct InflateState *state;
|
||||
const unsigned char *in; /* local strm->next_in */
|
||||
const unsigned char *last; /* have enough input while in < last */
|
||||
unsigned char *out; /* local strm->next_out */
|
||||
unsigned char *beg; /* inflate()'s initial strm->next_out */
|
||||
unsigned char *end; /* while out < end, enough space available */
|
||||
unsigned char *limit; /* safety limit for chunky copies */
|
||||
#ifdef INFLATE_STRICT
|
||||
unsigned dmax; /* maximum distance from zlib header */
|
||||
#endif
|
||||
unsigned wsize; /* window size or zero if not using window */
|
||||
unsigned whave; /* valid bytes in the window */
|
||||
unsigned wnext; /* window write index */
|
||||
unsigned char *window; /* allocated sliding window, if wsize != 0 */
|
||||
uint64_t hold; /* local strm->hold */
|
||||
unsigned bits; /* local strm->bits */
|
||||
const struct zcode *lcode; /* local strm->lencode */
|
||||
const struct zcode *dcode; /* local strm->distcode */
|
||||
unsigned lmask; /* mask for first level of length codes */
|
||||
unsigned dmask; /* mask for first level of distance codes */
|
||||
struct zcode here; /* retrieved table entry */
|
||||
unsigned op; /* code bits, operation, extra bits, or */
|
||||
/* window position, window bytes to copy */
|
||||
unsigned len; /* match length, unused bytes */
|
||||
unsigned dist; /* match distance */
|
||||
unsigned char *from; /* where to copy match from */
|
||||
|
||||
/* copy state to local variables */
|
||||
state = (struct InflateState *)strm->state;
|
||||
in = strm->next_in;
|
||||
last = in + (strm->avail_in - (INFLATE_FAST_MIN_INPUT - 1));
|
||||
out = strm->next_out;
|
||||
beg = out - (start - strm->avail_out);
|
||||
end = out + (strm->avail_out - (INFLATE_FAST_MIN_OUTPUT - 1));
|
||||
limit = out + strm->avail_out;
|
||||
#ifdef INFLATE_STRICT
|
||||
dmax = state->dmax;
|
||||
#endif
|
||||
wsize = state->wsize;
|
||||
whave = state->whave;
|
||||
wnext = (state->wnext == 0 && whave >= wsize) ? wsize : state->wnext;
|
||||
window = state->window;
|
||||
hold = state->hold;
|
||||
bits = state->bits;
|
||||
lcode = state->lencode;
|
||||
dcode = state->distcode;
|
||||
lmask = (1U << state->lenbits) - 1;
|
||||
dmask = (1U << state->distbits) - 1;
|
||||
|
||||
/* decode literals and length/distances until end-of-block or not enough
|
||||
input data or output space */
|
||||
do {
|
||||
if (bits < 15) {
|
||||
hold |= READ64LE(in) << bits;
|
||||
in += 6;
|
||||
bits += 48;
|
||||
}
|
||||
here = lcode[hold & lmask];
|
||||
dolen:
|
||||
op = (unsigned)(here.bits);
|
||||
hold >>= op;
|
||||
bits -= op;
|
||||
op = (unsigned)(here.op);
|
||||
if (op == 0) { /* literal */
|
||||
Tracevv((stderr,
|
||||
here.val >= 0x20 && here.val < 0x7f
|
||||
? "inflate: literal '%c'\n"
|
||||
: "inflate: literal 0x%02x\n",
|
||||
here.val));
|
||||
*out++ = (unsigned char)(here.val);
|
||||
} else if (op & 16) { /* length base */
|
||||
len = (unsigned)(here.val);
|
||||
op &= 15; /* number of extra bits */
|
||||
if (op) {
|
||||
if (bits < op) {
|
||||
hold |= READ64LE(in) << bits;
|
||||
in += 6;
|
||||
bits += 48;
|
||||
}
|
||||
len += (unsigned)hold & ((1U << op) - 1);
|
||||
hold >>= op;
|
||||
bits -= op;
|
||||
}
|
||||
Tracevv((stderr, "inflate: length %u\n", len));
|
||||
if (bits < 15) {
|
||||
hold |= READ64LE(in) << bits;
|
||||
in += 6;
|
||||
bits += 48;
|
||||
}
|
||||
here = dcode[hold & dmask];
|
||||
dodist:
|
||||
op = (unsigned)(here.bits);
|
||||
hold >>= op;
|
||||
bits -= op;
|
||||
op = (unsigned)(here.op);
|
||||
if (op & 16) { /* distance base */
|
||||
dist = (unsigned)(here.val);
|
||||
op &= 15; /* number of extra bits */
|
||||
if (bits < op) {
|
||||
hold |= READ64LE(in) << bits;
|
||||
in += 6;
|
||||
bits += 48;
|
||||
}
|
||||
dist += (unsigned)hold & ((1U << op) - 1);
|
||||
#ifdef INFLATE_STRICT
|
||||
if (dist > dmax) {
|
||||
strm->msg = (char *)"invalid distance too far back";
|
||||
state->mode = BAD;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
hold >>= op;
|
||||
bits -= op;
|
||||
Tracevv((stderr, "inflate: distance %u\n", dist));
|
||||
op = (unsigned)(out - beg); /* max distance in output */
|
||||
if (dist > op) { /* see if copy from window */
|
||||
op = dist - op; /* distance back in window */
|
||||
if (op > whave) {
|
||||
if (state->sane) {
|
||||
strm->msg = (char *)"invalid distance too far back";
|
||||
state->mode = BAD;
|
||||
break;
|
||||
}
|
||||
#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
|
||||
if (len <= op - whave) {
|
||||
do {
|
||||
*out++ = 0;
|
||||
} while (--len);
|
||||
continue;
|
||||
}
|
||||
len -= op - whave;
|
||||
do {
|
||||
*out++ = 0;
|
||||
} while (--op > whave);
|
||||
if (op == 0) {
|
||||
from = out - dist;
|
||||
do {
|
||||
*out++ = *from++;
|
||||
} while (--len);
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
from = window;
|
||||
if (wnext >= op) { /* contiguous in window */
|
||||
from += wnext - op;
|
||||
} else { /* wrap around window */
|
||||
op -= wnext;
|
||||
from += wsize - op;
|
||||
if (op < len) { /* some from end of window */
|
||||
len -= op;
|
||||
out = chunkcopy_safe(out, from, op, limit);
|
||||
from = window; /* more from start of window */
|
||||
op = wnext;
|
||||
/* This (rare) case can create a situation where
|
||||
the first chunkcopy below must be checked.
|
||||
*/
|
||||
}
|
||||
}
|
||||
if (op < len) { /* still need some from output */
|
||||
out = chunkcopy_safe(out, from, op, limit);
|
||||
len -= op;
|
||||
/* When dist is small the amount of data that can be
|
||||
copied from the window is also small, and progress
|
||||
towards the dangerous end of the output buffer is
|
||||
also small. This means that for trivial memsets and
|
||||
for chunkunroll_relaxed() a safety check is
|
||||
unnecessary. However, these conditions may not be
|
||||
entered at all, and in that case it's possible that
|
||||
the main copy is near the end.
|
||||
*/
|
||||
out = chunkunroll_relaxed(out, &dist, &len);
|
||||
out = chunkcopy_safe(out, out - dist, len, limit);
|
||||
} else {
|
||||
/* from points to window, so there is no risk of
|
||||
overlapping pointers requiring memset-like behaviour
|
||||
*/
|
||||
out = chunkcopy_safe(out, from, len, limit);
|
||||
}
|
||||
} else {
|
||||
/* Whole reference is in range of current output. No
|
||||
range checks are necessary because we start with room
|
||||
for at least 258 bytes of output, so unroll and roundoff
|
||||
operations can write beyond `out+len` so long as they
|
||||
stay within 258 bytes of `out`.
|
||||
*/
|
||||
out = chunkcopy_lapped_relaxed(out, dist, len);
|
||||
}
|
||||
} else if ((op & 64) == 0) { /* 2nd level distance code */
|
||||
here = dcode[here.val + (hold & ((1U << op) - 1))];
|
||||
goto dodist;
|
||||
} else {
|
||||
strm->msg = (char *)"invalid distance code";
|
||||
state->mode = BAD;
|
||||
break;
|
||||
}
|
||||
} else if ((op & 64) == 0) { /* 2nd level length code */
|
||||
here = lcode[here.val + (hold & ((1U << op) - 1))];
|
||||
goto dolen;
|
||||
} else if (op & 32) { /* end-of-block */
|
||||
Tracevv((stderr, "inflate: end of block\n"));
|
||||
state->mode = TYPE;
|
||||
break;
|
||||
} else {
|
||||
strm->msg = (char *)"invalid literal/length code";
|
||||
state->mode = BAD;
|
||||
break;
|
||||
}
|
||||
} while (in < last && out < end);
|
||||
|
||||
/* return unused bytes (on entry, bits < 8, so in won't go too far back) */
|
||||
len = bits >> 3;
|
||||
in -= len;
|
||||
bits -= len << 3;
|
||||
hold &= (1U << bits) - 1;
|
||||
|
||||
/* update state and return */
|
||||
strm->next_in = in;
|
||||
strm->next_out = out;
|
||||
strm->avail_in =
|
||||
(unsigned)(in < last ? (INFLATE_FAST_MIN_INPUT - 1) + (last - in)
|
||||
: (INFLATE_FAST_MIN_INPUT - 1) - (in - last));
|
||||
strm->avail_out =
|
||||
(unsigned)(out < end ? (INFLATE_FAST_MIN_OUTPUT - 1) + (end - out)
|
||||
: (INFLATE_FAST_MIN_OUTPUT - 1) - (out - end));
|
||||
state->hold = hold;
|
||||
state->bits = bits;
|
||||
|
||||
Assert((state->hold >> state->bits) == 0, "invalid input data state");
|
||||
}
|
122
third_party/zlib/inffixed.c
vendored
Normal file
122
third_party/zlib/inffixed.c
vendored
Normal file
|
@ -0,0 +1,122 @@
|
|||
#include "third_party/zlib/inftrees.h"
|
||||
|
||||
/**
|
||||
* @fileoverview tables for decoding fixed codes
|
||||
* @note generated by makefixed()
|
||||
*/
|
||||
|
||||
const struct zcode kZlibLenfix[512] = {
|
||||
{96, 7, 0}, {0, 8, 80}, {0, 8, 16}, {20, 8, 115}, {18, 7, 31},
|
||||
{0, 8, 112}, {0, 8, 48}, {0, 9, 192}, {16, 7, 10}, {0, 8, 96},
|
||||
{0, 8, 32}, {0, 9, 160}, {0, 8, 0}, {0, 8, 128}, {0, 8, 64},
|
||||
{0, 9, 224}, {16, 7, 6}, {0, 8, 88}, {0, 8, 24}, {0, 9, 144},
|
||||
{19, 7, 59}, {0, 8, 120}, {0, 8, 56}, {0, 9, 208}, {17, 7, 17},
|
||||
{0, 8, 104}, {0, 8, 40}, {0, 9, 176}, {0, 8, 8}, {0, 8, 136},
|
||||
{0, 8, 72}, {0, 9, 240}, {16, 7, 4}, {0, 8, 84}, {0, 8, 20},
|
||||
{21, 8, 227}, {19, 7, 43}, {0, 8, 116}, {0, 8, 52}, {0, 9, 200},
|
||||
{17, 7, 13}, {0, 8, 100}, {0, 8, 36}, {0, 9, 168}, {0, 8, 4},
|
||||
{0, 8, 132}, {0, 8, 68}, {0, 9, 232}, {16, 7, 8}, {0, 8, 92},
|
||||
{0, 8, 28}, {0, 9, 152}, {20, 7, 83}, {0, 8, 124}, {0, 8, 60},
|
||||
{0, 9, 216}, {18, 7, 23}, {0, 8, 108}, {0, 8, 44}, {0, 9, 184},
|
||||
{0, 8, 12}, {0, 8, 140}, {0, 8, 76}, {0, 9, 248}, {16, 7, 3},
|
||||
{0, 8, 82}, {0, 8, 18}, {21, 8, 163}, {19, 7, 35}, {0, 8, 114},
|
||||
{0, 8, 50}, {0, 9, 196}, {17, 7, 11}, {0, 8, 98}, {0, 8, 34},
|
||||
{0, 9, 164}, {0, 8, 2}, {0, 8, 130}, {0, 8, 66}, {0, 9, 228},
|
||||
{16, 7, 7}, {0, 8, 90}, {0, 8, 26}, {0, 9, 148}, {20, 7, 67},
|
||||
{0, 8, 122}, {0, 8, 58}, {0, 9, 212}, {18, 7, 19}, {0, 8, 106},
|
||||
{0, 8, 42}, {0, 9, 180}, {0, 8, 10}, {0, 8, 138}, {0, 8, 74},
|
||||
{0, 9, 244}, {16, 7, 5}, {0, 8, 86}, {0, 8, 22}, {64, 8, 0},
|
||||
{19, 7, 51}, {0, 8, 118}, {0, 8, 54}, {0, 9, 204}, {17, 7, 15},
|
||||
{0, 8, 102}, {0, 8, 38}, {0, 9, 172}, {0, 8, 6}, {0, 8, 134},
|
||||
{0, 8, 70}, {0, 9, 236}, {16, 7, 9}, {0, 8, 94}, {0, 8, 30},
|
||||
{0, 9, 156}, {20, 7, 99}, {0, 8, 126}, {0, 8, 62}, {0, 9, 220},
|
||||
{18, 7, 27}, {0, 8, 110}, {0, 8, 46}, {0, 9, 188}, {0, 8, 14},
|
||||
{0, 8, 142}, {0, 8, 78}, {0, 9, 252}, {96, 7, 0}, {0, 8, 81},
|
||||
{0, 8, 17}, {21, 8, 131}, {18, 7, 31}, {0, 8, 113}, {0, 8, 49},
|
||||
{0, 9, 194}, {16, 7, 10}, {0, 8, 97}, {0, 8, 33}, {0, 9, 162},
|
||||
{0, 8, 1}, {0, 8, 129}, {0, 8, 65}, {0, 9, 226}, {16, 7, 6},
|
||||
{0, 8, 89}, {0, 8, 25}, {0, 9, 146}, {19, 7, 59}, {0, 8, 121},
|
||||
{0, 8, 57}, {0, 9, 210}, {17, 7, 17}, {0, 8, 105}, {0, 8, 41},
|
||||
{0, 9, 178}, {0, 8, 9}, {0, 8, 137}, {0, 8, 73}, {0, 9, 242},
|
||||
{16, 7, 4}, {0, 8, 85}, {0, 8, 21}, {16, 8, 258}, {19, 7, 43},
|
||||
{0, 8, 117}, {0, 8, 53}, {0, 9, 202}, {17, 7, 13}, {0, 8, 101},
|
||||
{0, 8, 37}, {0, 9, 170}, {0, 8, 5}, {0, 8, 133}, {0, 8, 69},
|
||||
{0, 9, 234}, {16, 7, 8}, {0, 8, 93}, {0, 8, 29}, {0, 9, 154},
|
||||
{20, 7, 83}, {0, 8, 125}, {0, 8, 61}, {0, 9, 218}, {18, 7, 23},
|
||||
{0, 8, 109}, {0, 8, 45}, {0, 9, 186}, {0, 8, 13}, {0, 8, 141},
|
||||
{0, 8, 77}, {0, 9, 250}, {16, 7, 3}, {0, 8, 83}, {0, 8, 19},
|
||||
{21, 8, 195}, {19, 7, 35}, {0, 8, 115}, {0, 8, 51}, {0, 9, 198},
|
||||
{17, 7, 11}, {0, 8, 99}, {0, 8, 35}, {0, 9, 166}, {0, 8, 3},
|
||||
{0, 8, 131}, {0, 8, 67}, {0, 9, 230}, {16, 7, 7}, {0, 8, 91},
|
||||
{0, 8, 27}, {0, 9, 150}, {20, 7, 67}, {0, 8, 123}, {0, 8, 59},
|
||||
{0, 9, 214}, {18, 7, 19}, {0, 8, 107}, {0, 8, 43}, {0, 9, 182},
|
||||
{0, 8, 11}, {0, 8, 139}, {0, 8, 75}, {0, 9, 246}, {16, 7, 5},
|
||||
{0, 8, 87}, {0, 8, 23}, {64, 8, 0}, {19, 7, 51}, {0, 8, 119},
|
||||
{0, 8, 55}, {0, 9, 206}, {17, 7, 15}, {0, 8, 103}, {0, 8, 39},
|
||||
{0, 9, 174}, {0, 8, 7}, {0, 8, 135}, {0, 8, 71}, {0, 9, 238},
|
||||
{16, 7, 9}, {0, 8, 95}, {0, 8, 31}, {0, 9, 158}, {20, 7, 99},
|
||||
{0, 8, 127}, {0, 8, 63}, {0, 9, 222}, {18, 7, 27}, {0, 8, 111},
|
||||
{0, 8, 47}, {0, 9, 190}, {0, 8, 15}, {0, 8, 143}, {0, 8, 79},
|
||||
{0, 9, 254}, {96, 7, 0}, {0, 8, 80}, {0, 8, 16}, {20, 8, 115},
|
||||
{18, 7, 31}, {0, 8, 112}, {0, 8, 48}, {0, 9, 193}, {16, 7, 10},
|
||||
{0, 8, 96}, {0, 8, 32}, {0, 9, 161}, {0, 8, 0}, {0, 8, 128},
|
||||
{0, 8, 64}, {0, 9, 225}, {16, 7, 6}, {0, 8, 88}, {0, 8, 24},
|
||||
{0, 9, 145}, {19, 7, 59}, {0, 8, 120}, {0, 8, 56}, {0, 9, 209},
|
||||
{17, 7, 17}, {0, 8, 104}, {0, 8, 40}, {0, 9, 177}, {0, 8, 8},
|
||||
{0, 8, 136}, {0, 8, 72}, {0, 9, 241}, {16, 7, 4}, {0, 8, 84},
|
||||
{0, 8, 20}, {21, 8, 227}, {19, 7, 43}, {0, 8, 116}, {0, 8, 52},
|
||||
{0, 9, 201}, {17, 7, 13}, {0, 8, 100}, {0, 8, 36}, {0, 9, 169},
|
||||
{0, 8, 4}, {0, 8, 132}, {0, 8, 68}, {0, 9, 233}, {16, 7, 8},
|
||||
{0, 8, 92}, {0, 8, 28}, {0, 9, 153}, {20, 7, 83}, {0, 8, 124},
|
||||
{0, 8, 60}, {0, 9, 217}, {18, 7, 23}, {0, 8, 108}, {0, 8, 44},
|
||||
{0, 9, 185}, {0, 8, 12}, {0, 8, 140}, {0, 8, 76}, {0, 9, 249},
|
||||
{16, 7, 3}, {0, 8, 82}, {0, 8, 18}, {21, 8, 163}, {19, 7, 35},
|
||||
{0, 8, 114}, {0, 8, 50}, {0, 9, 197}, {17, 7, 11}, {0, 8, 98},
|
||||
{0, 8, 34}, {0, 9, 165}, {0, 8, 2}, {0, 8, 130}, {0, 8, 66},
|
||||
{0, 9, 229}, {16, 7, 7}, {0, 8, 90}, {0, 8, 26}, {0, 9, 149},
|
||||
{20, 7, 67}, {0, 8, 122}, {0, 8, 58}, {0, 9, 213}, {18, 7, 19},
|
||||
{0, 8, 106}, {0, 8, 42}, {0, 9, 181}, {0, 8, 10}, {0, 8, 138},
|
||||
{0, 8, 74}, {0, 9, 245}, {16, 7, 5}, {0, 8, 86}, {0, 8, 22},
|
||||
{64, 8, 0}, {19, 7, 51}, {0, 8, 118}, {0, 8, 54}, {0, 9, 205},
|
||||
{17, 7, 15}, {0, 8, 102}, {0, 8, 38}, {0, 9, 173}, {0, 8, 6},
|
||||
{0, 8, 134}, {0, 8, 70}, {0, 9, 237}, {16, 7, 9}, {0, 8, 94},
|
||||
{0, 8, 30}, {0, 9, 157}, {20, 7, 99}, {0, 8, 126}, {0, 8, 62},
|
||||
{0, 9, 221}, {18, 7, 27}, {0, 8, 110}, {0, 8, 46}, {0, 9, 189},
|
||||
{0, 8, 14}, {0, 8, 142}, {0, 8, 78}, {0, 9, 253}, {96, 7, 0},
|
||||
{0, 8, 81}, {0, 8, 17}, {21, 8, 131}, {18, 7, 31}, {0, 8, 113},
|
||||
{0, 8, 49}, {0, 9, 195}, {16, 7, 10}, {0, 8, 97}, {0, 8, 33},
|
||||
{0, 9, 163}, {0, 8, 1}, {0, 8, 129}, {0, 8, 65}, {0, 9, 227},
|
||||
{16, 7, 6}, {0, 8, 89}, {0, 8, 25}, {0, 9, 147}, {19, 7, 59},
|
||||
{0, 8, 121}, {0, 8, 57}, {0, 9, 211}, {17, 7, 17}, {0, 8, 105},
|
||||
{0, 8, 41}, {0, 9, 179}, {0, 8, 9}, {0, 8, 137}, {0, 8, 73},
|
||||
{0, 9, 243}, {16, 7, 4}, {0, 8, 85}, {0, 8, 21}, {16, 8, 258},
|
||||
{19, 7, 43}, {0, 8, 117}, {0, 8, 53}, {0, 9, 203}, {17, 7, 13},
|
||||
{0, 8, 101}, {0, 8, 37}, {0, 9, 171}, {0, 8, 5}, {0, 8, 133},
|
||||
{0, 8, 69}, {0, 9, 235}, {16, 7, 8}, {0, 8, 93}, {0, 8, 29},
|
||||
{0, 9, 155}, {20, 7, 83}, {0, 8, 125}, {0, 8, 61}, {0, 9, 219},
|
||||
{18, 7, 23}, {0, 8, 109}, {0, 8, 45}, {0, 9, 187}, {0, 8, 13},
|
||||
{0, 8, 141}, {0, 8, 77}, {0, 9, 251}, {16, 7, 3}, {0, 8, 83},
|
||||
{0, 8, 19}, {21, 8, 195}, {19, 7, 35}, {0, 8, 115}, {0, 8, 51},
|
||||
{0, 9, 199}, {17, 7, 11}, {0, 8, 99}, {0, 8, 35}, {0, 9, 167},
|
||||
{0, 8, 3}, {0, 8, 131}, {0, 8, 67}, {0, 9, 231}, {16, 7, 7},
|
||||
{0, 8, 91}, {0, 8, 27}, {0, 9, 151}, {20, 7, 67}, {0, 8, 123},
|
||||
{0, 8, 59}, {0, 9, 215}, {18, 7, 19}, {0, 8, 107}, {0, 8, 43},
|
||||
{0, 9, 183}, {0, 8, 11}, {0, 8, 139}, {0, 8, 75}, {0, 9, 247},
|
||||
{16, 7, 5}, {0, 8, 87}, {0, 8, 23}, {64, 8, 0}, {19, 7, 51},
|
||||
{0, 8, 119}, {0, 8, 55}, {0, 9, 207}, {17, 7, 15}, {0, 8, 103},
|
||||
{0, 8, 39}, {0, 9, 175}, {0, 8, 7}, {0, 8, 135}, {0, 8, 71},
|
||||
{0, 9, 239}, {16, 7, 9}, {0, 8, 95}, {0, 8, 31}, {0, 9, 159},
|
||||
{20, 7, 99}, {0, 8, 127}, {0, 8, 63}, {0, 9, 223}, {18, 7, 27},
|
||||
{0, 8, 111}, {0, 8, 47}, {0, 9, 191}, {0, 8, 15}, {0, 8, 143},
|
||||
{0, 8, 79}, {0, 9, 255},
|
||||
};
|
||||
|
||||
const struct zcode kZlibDistfix[32] = {
|
||||
{16, 5, 1}, {23, 5, 257}, {19, 5, 17}, {27, 5, 4097}, {17, 5, 5},
|
||||
{25, 5, 1025}, {21, 5, 65}, {29, 5, 16385}, {16, 5, 3}, {24, 5, 513},
|
||||
{20, 5, 33}, {28, 5, 8193}, {18, 5, 9}, {26, 5, 2049}, {22, 5, 129},
|
||||
{64, 5, 0}, {16, 5, 2}, {23, 5, 385}, {19, 5, 25}, {27, 5, 6145},
|
||||
{17, 5, 7}, {25, 5, 1537}, {21, 5, 97}, {29, 5, 24577}, {16, 5, 4},
|
||||
{24, 5, 769}, {20, 5, 49}, {28, 5, 12289}, {18, 5, 13}, {26, 5, 3073},
|
||||
{22, 5, 193}, {64, 5, 0},
|
||||
};
|
1483
third_party/zlib/inflate.c
vendored
Normal file
1483
third_party/zlib/inflate.c
vendored
Normal file
File diff suppressed because it is too large
Load diff
144
third_party/zlib/inflate.h
vendored
Normal file
144
third_party/zlib/inflate.h
vendored
Normal file
|
@ -0,0 +1,144 @@
|
|||
#ifndef COSMOPOLITAN_THIRD_PARTY_ZLIB_INFLATE_H_
|
||||
#define COSMOPOLITAN_THIRD_PARTY_ZLIB_INFLATE_H_
|
||||
#include "third_party/zlib/inftrees.h"
|
||||
#include "third_party/zlib/zlib.h"
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
/* inflate.h -- internal inflate state definition
|
||||
* Copyright (C) 1995-2016 Mark Adler
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
/* WARNING: this file should *not* be used by applications. It is
|
||||
part of the implementation of the compression library and is
|
||||
subject to change. Applications should only use zlib.h.
|
||||
*/
|
||||
|
||||
/* define NO_GZIP when compiling if you want to disable gzip header and
|
||||
trailer decoding by inflate(). NO_GZIP would be used to avoid linking in
|
||||
the crc code when it is not needed. For shared libraries, gzip decoding
|
||||
should be left enabled. */
|
||||
#ifndef NO_GZIP
|
||||
#define GUNZIP
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Possible inflate modes between inflate() calls
|
||||
*
|
||||
* State transitions between modes -
|
||||
*
|
||||
* (most modes can go to BAD or MEM on error -- not shown for clarity)
|
||||
*
|
||||
* Process header:
|
||||
* HEAD → (gzip) or (zlib) or (raw)
|
||||
* (gzip) → FLAGS → TIME → OS → EXLEN → EXTRA → NAME → COMMENT →
|
||||
* HCRC → TYPE
|
||||
* (zlib) → DICTID or TYPE
|
||||
* DICTID → DICT → TYPE
|
||||
* (raw) → TYPEDO
|
||||
* Read deflate blocks:
|
||||
* TYPE → TYPEDO → STORED or TABLE or LEN_ or CHECK
|
||||
* STORED → COPY_ → COPY → TYPE
|
||||
* TABLE → LENLENS → CODELENS → LEN_
|
||||
* LEN_ → LEN
|
||||
* Read deflate codes in fixed or dynamic block:
|
||||
* LEN → LENEXT or LIT or TYPE
|
||||
* LENEXT → DIST → DISTEXT → MATCH → LEN
|
||||
* LIT → LEN
|
||||
* Process trailer:
|
||||
* CHECK → LENGTH → DONE
|
||||
*/
|
||||
typedef enum {
|
||||
HEAD = 16180, /* i: waiting for magic header */
|
||||
FLAGS, /* i: waiting for method and flags (gzip) */
|
||||
TIME, /* i: waiting for modification time (gzip) */
|
||||
OS, /* i: waiting for extra flags and operating system (gzip) */
|
||||
EXLEN, /* i: waiting for extra length (gzip) */
|
||||
EXTRA, /* i: waiting for extra bytes (gzip) */
|
||||
NAME, /* i: waiting for end of file name (gzip) */
|
||||
COMMENT, /* i: waiting for end of comment (gzip) */
|
||||
HCRC, /* i: waiting for header crc (gzip) */
|
||||
DICTID, /* i: waiting for dictionary check value */
|
||||
DICT, /* waiting for inflateSetDictionary() call */
|
||||
TYPE, /* i: waiting for type bits, including last-flag bit */
|
||||
TYPEDO, /* i: same, but skip check to exit inflate on new block */
|
||||
STORED, /* i: waiting for stored size (length and complement) */
|
||||
COPY_, /* i/o: same as COPY below, but only first time in */
|
||||
COPY, /* i/o: waiting for input or output to copy stored block */
|
||||
TABLE, /* i: waiting for dynamic block table lengths */
|
||||
LENLENS, /* i: waiting for code length code lengths */
|
||||
CODELENS, /* i: waiting for length/lit and distance code lengths */
|
||||
LEN_, /* i: same as LEN below, but only first time in */
|
||||
LEN, /* i: waiting for length/lit/eob code */
|
||||
LENEXT, /* i: waiting for length extra bits */
|
||||
DIST, /* i: waiting for distance code */
|
||||
DISTEXT, /* i: waiting for distance extra bits */
|
||||
MATCH, /* o: waiting for output space to copy string */
|
||||
LIT, /* o: waiting for output space to write literal */
|
||||
CHECK, /* i: waiting for 32-bit check value */
|
||||
LENGTH, /* i: waiting for 32-bit length (gzip) */
|
||||
DONE, /* finished check, done -- remain here until reset */
|
||||
BAD, /* got a data error -- remain here until reset */
|
||||
MEM, /* got an inflate() memory error -- remain here until reset */
|
||||
SYNC /* looking for synchronization bytes to restart inflate() */
|
||||
} inflate_mode;
|
||||
|
||||
/**
|
||||
* State maintained between inflate() calls -- approximately 7K bytes,
|
||||
* not including the allocated sliding window, which is up to 32K bytes.
|
||||
*/
|
||||
struct InflateState {
|
||||
z_streamp strm; /* pointer back to this zlib stream */
|
||||
inflate_mode mode; /* current inflate mode */
|
||||
int last; /* true if processing last block */
|
||||
int wrap; /* bit 0 true for zlib, bit 1 true for gzip,
|
||||
bit 2 true to validate check value */
|
||||
int havedict; /* true if dictionary provided */
|
||||
int flags; /* gzip header method and flags (0 if zlib) */
|
||||
unsigned dmax; /* zlib header max distance (INFLATE_STRICT) */
|
||||
unsigned long check; /* protected copy of check value */
|
||||
unsigned long total; /* protected copy of output count */
|
||||
gz_headerp head; /* where to save gzip header information */
|
||||
|
||||
/* sliding window */
|
||||
unsigned wbits; /* log base 2 of requested window size */
|
||||
unsigned wsize; /* window size or zero if not using window */
|
||||
unsigned whave; /* valid bytes in the window */
|
||||
unsigned wnext; /* window write index */
|
||||
unsigned char *window; /* allocated sliding window, if needed */
|
||||
|
||||
/* bit accumulator */
|
||||
unsigned long hold; /* input bit accumulator */
|
||||
unsigned bits; /* number of bits in "in" */
|
||||
|
||||
/* for string and stored block copying */
|
||||
unsigned length; /* literal or length of data to copy */
|
||||
unsigned offset; /* distance back to copy string from */
|
||||
|
||||
/* for table and code decoding */
|
||||
unsigned extra; /* extra bits needed */
|
||||
|
||||
/* fixed and dynamic code tables */
|
||||
const struct zcode *lencode; /* starting table for length/literal codes */
|
||||
const struct zcode *distcode; /* starting table for distance codes */
|
||||
unsigned lenbits; /* index bits for lencode */
|
||||
unsigned distbits; /* index bits for distcode */
|
||||
|
||||
/* dynamic table building */
|
||||
unsigned ncode; /* number of code length code lengths */
|
||||
unsigned nlen; /* number of length code lengths */
|
||||
unsigned ndist; /* number of distance code lengths */
|
||||
unsigned have; /* number of code lengths in lens[] */
|
||||
struct zcode *next; /* next available space in codes[] */
|
||||
unsigned short lens[320]; /* temporary storage for code lengths */
|
||||
unsigned short work[288]; /* work area for code table building */
|
||||
struct zcode codes[ENOUGH]; /* space for code tables */
|
||||
int sane; /* if false, allow invalid distance too far */
|
||||
int back; /* bits back of last unprocessed length/lit */
|
||||
unsigned was; /* initial length of match */
|
||||
};
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_THIRD_PARTY_ZLIB_INFLATE_H_ */
|
26
third_party/zlib/inflateinit.S
vendored
Normal file
26
third_party/zlib/inflateinit.S
vendored
Normal file
|
@ -0,0 +1,26 @@
|
|||
/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
|
||||
│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "third_party/zlib/zutil.h"
|
||||
#include "libc/macros.h"
|
||||
|
||||
inflateInit:
|
||||
mov $DEF_WBITS,%esi
|
||||
jmp inflateInit2
|
||||
.endfn inflateInit,globl
|
305
third_party/zlib/inftrees.c
vendored
Normal file
305
third_party/zlib/inftrees.c
vendored
Normal file
|
@ -0,0 +1,305 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=4 sts=4 sw=4 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 1995-2017 Mark Adler │
|
||||
│ Use of this source code is governed by the BSD-style licenses that can │
|
||||
│ be found in the third_party/zlib/LICENSE file. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "third_party/zlib/inftrees.h"
|
||||
#include "third_party/zlib/zutil.h"
|
||||
|
||||
asm(".ident\t\"\\n\\n\
|
||||
inflate 1.2.11 (zlib License)\\n\
|
||||
Copyright 1995-2017 Mark Adler\\n\
|
||||
Invented 1990 Phillip Walter Katz\"");
|
||||
|
||||
/**
|
||||
* @fileoverview Generate Huffman trees for efficient decoding.
|
||||
*/
|
||||
|
||||
#define MAXBITS 15
|
||||
|
||||
/* Length codes 257..285 base */
|
||||
static const uint16_t kZlibDeflateLbase[31] = {
|
||||
3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
|
||||
35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
|
||||
|
||||
/* Length codes 257..285 extra */
|
||||
static const uint16_t kZlibDeflateLext[31] = {
|
||||
16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18,
|
||||
19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 77, 202};
|
||||
|
||||
/* Distance codes 0..29 base */
|
||||
static const uint16_t kZlibDeflateDbase[32] = {
|
||||
1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33,
|
||||
49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537,
|
||||
2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577, 0, 0};
|
||||
|
||||
/* Distance codes 0..29 extra */
|
||||
static const uint16_t kZlibDeflateDext[32] = {
|
||||
16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22,
|
||||
23, 23, 24, 24, 25, 25, 26, 26, 27, 27, 28, 28, 29, 29, 64, 64};
|
||||
|
||||
/**
|
||||
* Builds set of tables to decode the provided canonical Huffman code.
|
||||
* The code lengths are lens[0..codes-1]. The result starts at *table,
|
||||
* whose indices are 0..2^bits-1. work is a writable array of at least
|
||||
* lens shorts, which is used as a work area. type is the type of code
|
||||
* to be generated, CODES, LENS, or DISTS. On return, zero is success,
|
||||
* -1 is an invalid code, and +1 means that ENOUGH isn't enough. table
|
||||
* on return points to the next available entry's address. bits is the
|
||||
* requested root table index bits, and on return it is the actual root
|
||||
* table index bits. It will differ if the request is greater than the
|
||||
* longest code or if it is less than the shortest code.
|
||||
*/
|
||||
int inflate_table(zcodetype type, uint16_t *lens, unsigned codes,
|
||||
struct zcode **table, unsigned *bits, uint16_t *work) {
|
||||
unsigned len; /* a code's length in bits */
|
||||
unsigned sym; /* index of code symbols */
|
||||
unsigned min, max; /* minimum and maximum code lengths */
|
||||
unsigned root; /* number of index bits for root table */
|
||||
unsigned curr; /* number of index bits for current table */
|
||||
unsigned drop; /* code bits to drop for sub-table */
|
||||
int left; /* number of prefix codes available */
|
||||
unsigned used; /* code entries in table used */
|
||||
unsigned huff; /* Huffman code */
|
||||
unsigned incr; /* for incrementing code, index */
|
||||
unsigned fill; /* index for replicating entries */
|
||||
unsigned low; /* low bits for current root entry */
|
||||
unsigned mask; /* mask for low root bits */
|
||||
struct zcode here; /* table entry for duplication */
|
||||
struct zcode *next; /* next available space in table */
|
||||
const uint16_t *base; /* base value table to use */
|
||||
const uint16_t *extra; /* extra bits table to use */
|
||||
unsigned match; /* use base and extra for symbol >= match */
|
||||
uint16_t count[MAXBITS + 1]; /* number of codes of each length */
|
||||
uint16_t offs[MAXBITS + 1]; /* offsets in table for each length */
|
||||
|
||||
/*
|
||||
Process a set of code lengths to create a canonical Huffman code. The
|
||||
code lengths are lens[0..codes-1]. Each length corresponds to the
|
||||
symbols 0..codes-1. The Huffman code is generated by first sorting the
|
||||
symbols by length from short to long, and retaining the symbol order
|
||||
for codes with equal lengths. Then the code starts with all zero bits
|
||||
for the first code of the shortest length, and the codes are integer
|
||||
increments for the same length, and zeros are appended as the length
|
||||
increases. For the deflate format, these bits are stored backwards
|
||||
from their more natural integer increment ordering, and so when the
|
||||
decoding tables are built in the large loop below, the integer codes
|
||||
are incremented backwards.
|
||||
|
||||
This routine assumes, but does not check, that all of the entries in
|
||||
lens[] are in the range 0..MAXBITS. The caller must assure this.
|
||||
1..MAXBITS is interpreted as that code length. zero means that that
|
||||
symbol does not occur in this code.
|
||||
|
||||
The codes are sorted by computing a count of codes for each length,
|
||||
creating from that a table of starting indices for each length in the
|
||||
sorted table, and then entering the symbols in order in the sorted
|
||||
table. The sorted table is work[], with that space being provided by
|
||||
the caller.
|
||||
|
||||
The length counts are used for other purposes as well, i.e. finding
|
||||
the minimum and maximum length codes, determining if there are any
|
||||
codes at all, checking for a valid set of lengths, and looking ahead
|
||||
at length counts to determine sub-table sizes when building the
|
||||
decoding tables.
|
||||
*/
|
||||
|
||||
/* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */
|
||||
for (len = 0; len <= MAXBITS; len++) count[len] = 0;
|
||||
for (sym = 0; sym < codes; sym++) count[lens[sym]]++;
|
||||
|
||||
/* bound code lengths, force root to be within code lengths */
|
||||
root = *bits;
|
||||
for (max = MAXBITS; max >= 1; max--) {
|
||||
if (count[max] != 0) break;
|
||||
}
|
||||
if (root > max) root = max;
|
||||
if (max == 0) { /* no symbols to code at all */
|
||||
here.op = (uint8_t)64; /* invalid code marker */
|
||||
here.bits = (uint8_t)1;
|
||||
here.val = (uint16_t)0;
|
||||
*(*table)++ = here; /* make a table to force an error */
|
||||
*(*table)++ = here;
|
||||
*bits = 1;
|
||||
return 0; /* no symbols, but wait for decoding to report error */
|
||||
}
|
||||
for (min = 1; min < max; min++)
|
||||
if (count[min] != 0) break;
|
||||
if (root < min) root = min;
|
||||
|
||||
/* check for an over-subscribed or incomplete set of lengths */
|
||||
left = 1;
|
||||
for (len = 1; len <= MAXBITS; len++) {
|
||||
left <<= 1;
|
||||
left -= count[len];
|
||||
if (left < 0) return -1; /* over-subscribed */
|
||||
}
|
||||
if (left > 0 && (type == CODES || max != 1)) return -1; /* incomplete set */
|
||||
|
||||
/* generate offsets into symbol table for each length for sorting */
|
||||
offs[1] = 0;
|
||||
for (len = 1; len < MAXBITS; len++) {
|
||||
offs[len + 1] = offs[len] + count[len];
|
||||
}
|
||||
|
||||
/* sort symbols by length, by symbol order within each length */
|
||||
for (sym = 0; sym < codes; sym++) {
|
||||
if (lens[sym] != 0) work[offs[lens[sym]]++] = (uint16_t)sym;
|
||||
}
|
||||
|
||||
/*
|
||||
Create and fill in decoding tables. In this loop, the table being
|
||||
filled is at next and has curr index bits. The code being used is
|
||||
huff with length len. That code is converted to an index by dropping
|
||||
drop bits off of the bottom. For codes where len is less than drop +
|
||||
curr, those top drop + curr - len bits are incremented through all
|
||||
values to fill the table with replicated entries.
|
||||
|
||||
root is the number of index bits for the root table. When len
|
||||
exceeds root, sub-tables are created pointed to by the root entry
|
||||
with an index of the low root bits of huff. This is saved in low to
|
||||
check for when a new sub-table should be started. drop is zero when
|
||||
the root table is being filled, and drop is root when sub-tables are
|
||||
being filled.
|
||||
|
||||
When a new sub-table is needed, it is necessary to look ahead in the
|
||||
code lengths to determine what size sub-table is needed. The length
|
||||
counts are used for this, and so count[] is decremented as codes are
|
||||
entered in the tables.
|
||||
|
||||
used keeps track of how many table entries have been allocated from
|
||||
the provided *table space. It is checked for LENS and DIST tables
|
||||
against the constants ENOUGH_LENS and ENOUGH_DISTS to guard against
|
||||
changes in the initial root table size constants. See the comments
|
||||
in inftrees.h for more information.
|
||||
|
||||
sym increments through all symbols, and the loop terminates when all
|
||||
codes of length max, i.e. all codes, have been processed. This
|
||||
routine permits incomplete codes, so another loop after this one
|
||||
fills in the rest of the decoding tables with invalid code markers.
|
||||
*/
|
||||
|
||||
/* set up for code type */
|
||||
switch (type) {
|
||||
case CODES:
|
||||
base = extra = work; /* dummy value--not used */
|
||||
match = 20;
|
||||
break;
|
||||
case LENS:
|
||||
base = kZlibDeflateLbase;
|
||||
extra = kZlibDeflateLext;
|
||||
match = 257;
|
||||
break;
|
||||
default: /* DISTS */
|
||||
base = kZlibDeflateDbase;
|
||||
extra = kZlibDeflateDext;
|
||||
match = 0;
|
||||
}
|
||||
|
||||
/* initialize state for loop */
|
||||
huff = 0; /* starting code */
|
||||
sym = 0; /* starting code symbol */
|
||||
len = min; /* starting code length */
|
||||
next = *table; /* current table to fill in */
|
||||
curr = root; /* current table index bits */
|
||||
drop = 0; /* current bits to drop from code for index */
|
||||
low = (unsigned)(-1); /* trigger new sub-table when len > root */
|
||||
used = 1U << root; /* use root table entries */
|
||||
mask = used - 1; /* mask for comparing low */
|
||||
|
||||
/* check available table space */
|
||||
if ((type == LENS && used > ENOUGH_LENS) ||
|
||||
(type == DISTS && used > ENOUGH_DISTS)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* process all codes and make table entries */
|
||||
for (;;) {
|
||||
/* create table entry */
|
||||
here.bits = (uint8_t)(len - drop);
|
||||
if (work[sym] + 1U < match) {
|
||||
here.op = (uint8_t)0;
|
||||
here.val = work[sym];
|
||||
} else if (work[sym] >= match) {
|
||||
here.op = (uint8_t)(extra[work[sym] - match]);
|
||||
here.val = base[work[sym] - match];
|
||||
} else {
|
||||
here.op = (uint8_t)(32 + 64); /* end of block */
|
||||
here.val = 0;
|
||||
}
|
||||
|
||||
/* replicate for those indices with low len bits equal to huff */
|
||||
incr = 1U << (len - drop);
|
||||
fill = 1U << curr;
|
||||
min = fill; /* save offset to next table */
|
||||
do {
|
||||
fill -= incr;
|
||||
next[(huff >> drop) + fill] = here;
|
||||
} while (fill != 0);
|
||||
|
||||
/* backwards increment the len-bit code huff */
|
||||
incr = 1U << (len - 1);
|
||||
while (huff & incr) incr >>= 1;
|
||||
if (incr != 0) {
|
||||
huff &= incr - 1;
|
||||
huff += incr;
|
||||
} else
|
||||
huff = 0;
|
||||
|
||||
/* go to next symbol, update count, len */
|
||||
sym++;
|
||||
if (--(count[len]) == 0) {
|
||||
if (len == max) break;
|
||||
len = lens[work[sym]];
|
||||
}
|
||||
|
||||
/* create new sub-table if needed */
|
||||
if (len > root && (huff & mask) != low) {
|
||||
/* if first time, transition to sub-tables */
|
||||
if (drop == 0) drop = root;
|
||||
|
||||
/* increment past last table */
|
||||
next += min; /* here min is 1 << curr */
|
||||
|
||||
/* determine length of next table */
|
||||
curr = len - drop;
|
||||
left = (int)(1u << curr);
|
||||
while (curr + drop < max) {
|
||||
left -= count[curr + drop];
|
||||
if (left <= 0) break;
|
||||
curr++;
|
||||
left <<= 1;
|
||||
}
|
||||
|
||||
/* check for enough space */
|
||||
used += 1U << curr;
|
||||
if ((type == LENS && used > ENOUGH_LENS) ||
|
||||
(type == DISTS && used > ENOUGH_DISTS)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* point entry in root table to sub-table */
|
||||
low = huff & mask;
|
||||
(*table)[low].op = (uint8_t)curr;
|
||||
(*table)[low].bits = (uint8_t)root;
|
||||
(*table)[low].val = (uint16_t)(next - *table);
|
||||
}
|
||||
}
|
||||
|
||||
/* fill in remaining table entry if code is incomplete (guaranteed to have
|
||||
at most one remaining entry, since if the code is incomplete, the
|
||||
maximum code length that was allowed to get this far is one bit) */
|
||||
if (huff != 0) {
|
||||
here.op = (uint8_t)64; /* invalid code marker */
|
||||
here.bits = (uint8_t)(len - drop);
|
||||
here.val = (uint16_t)0;
|
||||
next[huff] = here;
|
||||
}
|
||||
|
||||
/* set return parameters */
|
||||
*table += used;
|
||||
*bits = root;
|
||||
return 0;
|
||||
}
|
66
third_party/zlib/inftrees.h
vendored
Normal file
66
third_party/zlib/inftrees.h
vendored
Normal file
|
@ -0,0 +1,66 @@
|
|||
#ifndef COSMOPOLITAN_THIRD_PARTY_ZLIB_INFTREES_H_
|
||||
#define COSMOPOLITAN_THIRD_PARTY_ZLIB_INFTREES_H_
|
||||
|
||||
/* WARNING: this file should *not* be used by applications. It is
|
||||
part of the implementation of the compression library and is
|
||||
subject to change. Applications should only use zlib.h.
|
||||
*/
|
||||
|
||||
/* Maximum size of the dynamic table. The maximum number of code structures is
|
||||
1444, which is the sum of 852 for literal/length codes and 592 for distance
|
||||
codes. These values were found by exhaustive searches using the program
|
||||
examples/enough.c found in the zlib distribtution. The arguments to that
|
||||
program are the number of symbols, the initial root table size, and the
|
||||
maximum bit length of a code. "enough 286 9 15" for literal/length codes
|
||||
returns returns 852, and "enough 30 6 15" for distance codes returns 592.
|
||||
The initial root table size (9 or 6) is found in the fifth argument of the
|
||||
inflate_table() calls in inflate.c and infback.c. If the root table size is
|
||||
changed, then these maximum sizes would be need to be recalculated and
|
||||
updated. */
|
||||
#define ENOUGH_LENS 852
|
||||
#define ENOUGH_DISTS 592
|
||||
#define ENOUGH (ENOUGH_LENS + ENOUGH_DISTS)
|
||||
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
/* Structure for decoding tables. Each entry provides either the
|
||||
information needed to do the operation requested by the code that
|
||||
indexed that table entry, or it provides a pointer to another
|
||||
table that indexes more bits of the code. op indicates whether
|
||||
the entry is a pointer to another table, a literal, a length or
|
||||
distance, an end-of-block, or an invalid code. For a table
|
||||
pointer, the low four bits of op is the number of index bits of
|
||||
that table. For a length or distance, the low four bits of op
|
||||
is the number of extra bits to get after the code. bits is
|
||||
the number of bits in this code or part of the code to drop off
|
||||
of the bit buffer. val is the actual byte to output in the case
|
||||
of a literal, the base length or distance, or the offset from
|
||||
the current table to the next table. Each entry is four bytes. */
|
||||
struct zcode {
|
||||
unsigned char op; /* operation, extra bits, table bits */
|
||||
unsigned char bits; /* bits in this part of the code */
|
||||
unsigned short val; /* offset in table or code value */
|
||||
};
|
||||
|
||||
extern const struct zcode kZlibLenfix[512] hidden;
|
||||
extern const struct zcode kZlibDistfix[32] hidden;
|
||||
|
||||
/* op values as set by inflate_table():
|
||||
00000000 - literal
|
||||
0000tttt - table link, tttt != 0 is the number of table index bits
|
||||
0001eeee - length or distance, eeee is the number of extra bits
|
||||
01100000 - end of block
|
||||
01000000 - invalid code
|
||||
*/
|
||||
|
||||
/* Type of code to build for inflate_table() */
|
||||
typedef enum { CODES, LENS, DISTS } zcodetype;
|
||||
|
||||
int inflate_table(zcodetype type, unsigned short *lens, unsigned codes,
|
||||
struct zcode **table, unsigned *bits,
|
||||
unsigned short *work) hidden;
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_THIRD_PARTY_ZLIB_INFTREES_H_ */
|
26
third_party/zlib/internal.h
vendored
Normal file
26
third_party/zlib/internal.h
vendored
Normal file
|
@ -0,0 +1,26 @@
|
|||
#ifndef COSMOPOLITAN_THIRD_PARTY_ZLIB_INTERNAL_H_
|
||||
#define COSMOPOLITAN_THIRD_PARTY_ZLIB_INTERNAL_H_
|
||||
#include "third_party/zlib/deflate.h"
|
||||
|
||||
#define Z_CRC32_SSE42_MINIMUM_LENGTH 64
|
||||
#define Z_CRC32_SSE42_CHUNKSIZE_MASK 15
|
||||
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
unsigned deflate_read_buf(z_streamp, Bytef *, unsigned) hidden;
|
||||
void copy_with_crc(z_streamp, Bytef *, long) hidden;
|
||||
void crc_finalize(struct DeflateState *const) hidden;
|
||||
void crc_reset(struct DeflateState *const) hidden;
|
||||
uint32_t adler32_simd_(uint32_t, const unsigned char *, size_t) hidden;
|
||||
void crc_fold_init(struct DeflateState *const) hidden;
|
||||
void crc_fold_copy(struct DeflateState *const, unsigned char *,
|
||||
const unsigned char *, long) hidden;
|
||||
unsigned crc_fold_512to32(struct DeflateState *const) hidden;
|
||||
void fill_window_sse(struct DeflateState *) hidden;
|
||||
void *zcalloc(void *, unsigned, unsigned) hidden;
|
||||
void zcfree(void *, void *) hidden;
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_THIRD_PARTY_ZLIB_INTERNAL_H_ */
|
68
third_party/zlib/kdistcode.S
vendored
Normal file
68
third_party/zlib/kdistcode.S
vendored
Normal file
|
@ -0,0 +1,68 @@
|
|||
/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
|
||||
│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "third_party/zlib/deflate.h"
|
||||
#include "libc/macros.h"
|
||||
|
||||
.initbss 300,_init_kZlibDistCode
|
||||
kZlibDistCode:
|
||||
.zero DIST_CODE_LEN
|
||||
.endobj kZlibDistCode,globl,hidden
|
||||
.previous
|
||||
|
||||
.initro 300,_init_kZlibDistCode
|
||||
.LkZlibDistCode.rodata: /* 64 bytes (13%) */
|
||||
.byte 1,0x00 /* 00-00 ∅ */
|
||||
.byte 1,0x01 /* 01-01 ☺ */
|
||||
.byte 1,0x02 /* 02-02 ☻ */
|
||||
.byte 1,0x03 /* 03-03 ♥ */
|
||||
.byte 2,0x04 /* 04-05 ♦-♣ */
|
||||
.byte 2,0x05 /* 06-07 ♠-• */
|
||||
.byte 4,0x06 /* 08-0b ◘-♂ */
|
||||
.byte 4,0x07 /* 0c-0f ♀-☼ */
|
||||
.byte 8,0x08 /* 10-17 ►-↨ */
|
||||
.byte 8,0x09 /* 18-1f ↑-▼ */
|
||||
.byte 16,0x0a /* 20-2f -/ */
|
||||
.byte 16,0x0b /* 30-3f 0-? */
|
||||
.byte 32,0x0c /* 40-5f @-_ */
|
||||
.byte 32,0x0d /* 60-7f `-⌂ */
|
||||
.byte 64,0x0e /* 80-bf Ç-┐ */
|
||||
.byte 64,0x0f /* c0-ff └-λ */
|
||||
.byte 2,0x00 /* 100-101 */
|
||||
.byte 1,0x10 /* 102-102 */
|
||||
.byte 1,0x11 /* 103-103 */
|
||||
.byte 2,0x12 /* 104-105 */
|
||||
.byte 2,0x13 /* 106-107 */
|
||||
.byte 4,0x14 /* 108-10b */
|
||||
.byte 4,0x15 /* 10c-10f */
|
||||
.byte 8,0x16 /* 110-117 */
|
||||
.byte 8,0x17 /* 118-11f */
|
||||
.byte 16,0x18 /* 120-12f */
|
||||
.byte 16,0x19 /* 130-13f */
|
||||
.byte 32,0x1a /* 140-15f */
|
||||
.byte 32,0x1b /* 160-17f */
|
||||
.byte 64,0x1c /* 180-1bf */
|
||||
.byte 64,0x1d /* 1c0-1ff */
|
||||
.endobj .LkZlibDistCode.rodata
|
||||
.byte 0,0 /* terminator */
|
||||
.previous
|
||||
|
||||
.init.start 300,_init_kZlibDistCode
|
||||
call rldecode
|
||||
.init.end 300,_init_kZlibDistCode
|
68
third_party/zlib/klengthcode.S
vendored
Normal file
68
third_party/zlib/klengthcode.S
vendored
Normal file
|
@ -0,0 +1,68 @@
|
|||
/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
|
||||
│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "third_party/zlib/zutil.h"
|
||||
#include "libc/macros.h"
|
||||
|
||||
.initbss 300,_init_kZlibLengthCode
|
||||
kZlibLengthCode:
|
||||
.zero MAX_MATCH - MIN_MATCH + 1
|
||||
.endobj kZlibLengthCode,globl,hidden
|
||||
.previous
|
||||
|
||||
.initro 300,_init_kZlibLengthCode
|
||||
.LkZlibLengthCode.rodata: /* 64 bytes (25%) */
|
||||
.byte 1,0x00 /* 00-00 ∅ */
|
||||
.byte 1,0x01 /* 01-01 ☺ */
|
||||
.byte 1,0x02 /* 02-02 ☻ */
|
||||
.byte 1,0x03 /* 03-03 ♥ */
|
||||
.byte 1,0x04 /* 04-04 ♦ */
|
||||
.byte 1,0x05 /* 05-05 ♣ */
|
||||
.byte 1,0x06 /* 06-06 ♠ */
|
||||
.byte 1,0x07 /* 07-07 • */
|
||||
.byte 2,0x08 /* 08-09 ◘-○ */
|
||||
.byte 2,0x09 /* 0a-0b ◙-♂ */
|
||||
.byte 2,0x0a /* 0c-0d ♀-♪ */
|
||||
.byte 2,0x0b /* 0e-0f ♫-☼ */
|
||||
.byte 4,0x0c /* 10-13 ►-‼ */
|
||||
.byte 4,0x0d /* 14-17 ¶-↨ */
|
||||
.byte 4,0x0e /* 18-1b ↑-← */
|
||||
.byte 4,0x0f /* 1c-1f ∟-▼ */
|
||||
.byte 8,0x10 /* 20-27 -' */
|
||||
.byte 8,0x11 /* 28-2f (-/ */
|
||||
.byte 8,0x12 /* 30-37 0-7 */
|
||||
.byte 8,0x13 /* 38-3f 8-? */
|
||||
.byte 16,0x14 /* 40-4f @-O */
|
||||
.byte 16,0x15 /* 50-5f P-_ */
|
||||
.byte 16,0x16 /* 60-6f `-o */
|
||||
.byte 16,0x17 /* 70-7f p-⌂ */
|
||||
.byte 32,0x18 /* 80-9f Ç-ƒ */
|
||||
.byte 32,0x19 /* a0-bf á-┐ */
|
||||
.byte 32,0x1a /* c0-df └-▀ */
|
||||
.byte 31,0x1b /* e0-fe α-■ */
|
||||
.byte 1,0x1c /* ff-ff λ */
|
||||
.endobj .LkZlibLengthCode.rodata
|
||||
.byte 0,0 /* terminator */
|
||||
.byte 0,0,0,0 /* padding */
|
||||
.previous
|
||||
|
||||
.init.start 300,_init_kZlibLengthCode
|
||||
call rldecode
|
||||
lodsl
|
||||
.init.end 300,_init_kZlibLengthCode
|
10
third_party/zlib/kstaticdtree.c
vendored
Normal file
10
third_party/zlib/kstaticdtree.c
vendored
Normal file
|
@ -0,0 +1,10 @@
|
|||
#include "third_party/zlib/internal.h"
|
||||
|
||||
const ct_data kZlibStaticDtree[D_CODES] = {
|
||||
{{0}, {5}}, {{16}, {5}}, {{8}, {5}}, {{24}, {5}}, {{4}, {5}},
|
||||
{{20}, {5}}, {{12}, {5}}, {{28}, {5}}, {{2}, {5}}, {{18}, {5}},
|
||||
{{10}, {5}}, {{26}, {5}}, {{6}, {5}}, {{22}, {5}}, {{14}, {5}},
|
||||
{{30}, {5}}, {{1}, {5}}, {{17}, {5}}, {{9}, {5}}, {{25}, {5}},
|
||||
{{5}, {5}}, {{21}, {5}}, {{13}, {5}}, {{29}, {5}}, {{3}, {5}},
|
||||
{{19}, {5}}, {{11}, {5}}, {{27}, {5}}, {{7}, {5}}, {{23}, {5}},
|
||||
};
|
62
third_party/zlib/kstaticltree.c
vendored
Normal file
62
third_party/zlib/kstaticltree.c
vendored
Normal file
|
@ -0,0 +1,62 @@
|
|||
#include "third_party/zlib/internal.h"
|
||||
|
||||
const ct_data kZlibStaticLtree[L_CODES + 2] = {
|
||||
{{12}, {8}}, {{140}, {8}}, {{76}, {8}}, {{204}, {8}}, {{44}, {8}},
|
||||
{{172}, {8}}, {{108}, {8}}, {{236}, {8}}, {{28}, {8}}, {{156}, {8}},
|
||||
{{92}, {8}}, {{220}, {8}}, {{60}, {8}}, {{188}, {8}}, {{124}, {8}},
|
||||
{{252}, {8}}, {{2}, {8}}, {{130}, {8}}, {{66}, {8}}, {{194}, {8}},
|
||||
{{34}, {8}}, {{162}, {8}}, {{98}, {8}}, {{226}, {8}}, {{18}, {8}},
|
||||
{{146}, {8}}, {{82}, {8}}, {{210}, {8}}, {{50}, {8}}, {{178}, {8}},
|
||||
{{114}, {8}}, {{242}, {8}}, {{10}, {8}}, {{138}, {8}}, {{74}, {8}},
|
||||
{{202}, {8}}, {{42}, {8}}, {{170}, {8}}, {{106}, {8}}, {{234}, {8}},
|
||||
{{26}, {8}}, {{154}, {8}}, {{90}, {8}}, {{218}, {8}}, {{58}, {8}},
|
||||
{{186}, {8}}, {{122}, {8}}, {{250}, {8}}, {{6}, {8}}, {{134}, {8}},
|
||||
{{70}, {8}}, {{198}, {8}}, {{38}, {8}}, {{166}, {8}}, {{102}, {8}},
|
||||
{{230}, {8}}, {{22}, {8}}, {{150}, {8}}, {{86}, {8}}, {{214}, {8}},
|
||||
{{54}, {8}}, {{182}, {8}}, {{118}, {8}}, {{246}, {8}}, {{14}, {8}},
|
||||
{{142}, {8}}, {{78}, {8}}, {{206}, {8}}, {{46}, {8}}, {{174}, {8}},
|
||||
{{110}, {8}}, {{238}, {8}}, {{30}, {8}}, {{158}, {8}}, {{94}, {8}},
|
||||
{{222}, {8}}, {{62}, {8}}, {{190}, {8}}, {{126}, {8}}, {{254}, {8}},
|
||||
{{1}, {8}}, {{129}, {8}}, {{65}, {8}}, {{193}, {8}}, {{33}, {8}},
|
||||
{{161}, {8}}, {{97}, {8}}, {{225}, {8}}, {{17}, {8}}, {{145}, {8}},
|
||||
{{81}, {8}}, {{209}, {8}}, {{49}, {8}}, {{177}, {8}}, {{113}, {8}},
|
||||
{{241}, {8}}, {{9}, {8}}, {{137}, {8}}, {{73}, {8}}, {{201}, {8}},
|
||||
{{41}, {8}}, {{169}, {8}}, {{105}, {8}}, {{233}, {8}}, {{25}, {8}},
|
||||
{{153}, {8}}, {{89}, {8}}, {{217}, {8}}, {{57}, {8}}, {{185}, {8}},
|
||||
{{121}, {8}}, {{249}, {8}}, {{5}, {8}}, {{133}, {8}}, {{69}, {8}},
|
||||
{{197}, {8}}, {{37}, {8}}, {{165}, {8}}, {{101}, {8}}, {{229}, {8}},
|
||||
{{21}, {8}}, {{149}, {8}}, {{85}, {8}}, {{213}, {8}}, {{53}, {8}},
|
||||
{{181}, {8}}, {{117}, {8}}, {{245}, {8}}, {{13}, {8}}, {{141}, {8}},
|
||||
{{77}, {8}}, {{205}, {8}}, {{45}, {8}}, {{173}, {8}}, {{109}, {8}},
|
||||
{{237}, {8}}, {{29}, {8}}, {{157}, {8}}, {{93}, {8}}, {{221}, {8}},
|
||||
{{61}, {8}}, {{189}, {8}}, {{125}, {8}}, {{253}, {8}}, {{19}, {9}},
|
||||
{{275}, {9}}, {{147}, {9}}, {{403}, {9}}, {{83}, {9}}, {{339}, {9}},
|
||||
{{211}, {9}}, {{467}, {9}}, {{51}, {9}}, {{307}, {9}}, {{179}, {9}},
|
||||
{{435}, {9}}, {{115}, {9}}, {{371}, {9}}, {{243}, {9}}, {{499}, {9}},
|
||||
{{11}, {9}}, {{267}, {9}}, {{139}, {9}}, {{395}, {9}}, {{75}, {9}},
|
||||
{{331}, {9}}, {{203}, {9}}, {{459}, {9}}, {{43}, {9}}, {{299}, {9}},
|
||||
{{171}, {9}}, {{427}, {9}}, {{107}, {9}}, {{363}, {9}}, {{235}, {9}},
|
||||
{{491}, {9}}, {{27}, {9}}, {{283}, {9}}, {{155}, {9}}, {{411}, {9}},
|
||||
{{91}, {9}}, {{347}, {9}}, {{219}, {9}}, {{475}, {9}}, {{59}, {9}},
|
||||
{{315}, {9}}, {{187}, {9}}, {{443}, {9}}, {{123}, {9}}, {{379}, {9}},
|
||||
{{251}, {9}}, {{507}, {9}}, {{7}, {9}}, {{263}, {9}}, {{135}, {9}},
|
||||
{{391}, {9}}, {{71}, {9}}, {{327}, {9}}, {{199}, {9}}, {{455}, {9}},
|
||||
{{39}, {9}}, {{295}, {9}}, {{167}, {9}}, {{423}, {9}}, {{103}, {9}},
|
||||
{{359}, {9}}, {{231}, {9}}, {{487}, {9}}, {{23}, {9}}, {{279}, {9}},
|
||||
{{151}, {9}}, {{407}, {9}}, {{87}, {9}}, {{343}, {9}}, {{215}, {9}},
|
||||
{{471}, {9}}, {{55}, {9}}, {{311}, {9}}, {{183}, {9}}, {{439}, {9}},
|
||||
{{119}, {9}}, {{375}, {9}}, {{247}, {9}}, {{503}, {9}}, {{15}, {9}},
|
||||
{{271}, {9}}, {{143}, {9}}, {{399}, {9}}, {{79}, {9}}, {{335}, {9}},
|
||||
{{207}, {9}}, {{463}, {9}}, {{47}, {9}}, {{303}, {9}}, {{175}, {9}},
|
||||
{{431}, {9}}, {{111}, {9}}, {{367}, {9}}, {{239}, {9}}, {{495}, {9}},
|
||||
{{31}, {9}}, {{287}, {9}}, {{159}, {9}}, {{415}, {9}}, {{95}, {9}},
|
||||
{{351}, {9}}, {{223}, {9}}, {{479}, {9}}, {{63}, {9}}, {{319}, {9}},
|
||||
{{191}, {9}}, {{447}, {9}}, {{127}, {9}}, {{383}, {9}}, {{255}, {9}},
|
||||
{{511}, {9}}, {{0}, {7}}, {{64}, {7}}, {{32}, {7}}, {{96}, {7}},
|
||||
{{16}, {7}}, {{80}, {7}}, {{48}, {7}}, {{112}, {7}}, {{8}, {7}},
|
||||
{{72}, {7}}, {{40}, {7}}, {{104}, {7}}, {{24}, {7}}, {{88}, {7}},
|
||||
{{56}, {7}}, {{120}, {7}}, {{4}, {7}}, {{68}, {7}}, {{36}, {7}},
|
||||
{{100}, {7}}, {{20}, {7}}, {{84}, {7}}, {{52}, {7}}, {{116}, {7}},
|
||||
{{3}, {8}}, {{131}, {8}}, {{67}, {8}}, {{195}, {8}}, {{35}, {8}},
|
||||
{{163}, {8}}, {{99}, {8}}, {{227}, {8}},
|
||||
};
|
13
third_party/zlib/treeconst.c
vendored
Normal file
13
third_party/zlib/treeconst.c
vendored
Normal file
|
@ -0,0 +1,13 @@
|
|||
/* header created automatically with -DGEN_TREES_H */
|
||||
#include "third_party/zlib/internal.h"
|
||||
|
||||
const int kZlibBaseLength[LENGTH_CODES] = {
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24,
|
||||
28, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 0,
|
||||
};
|
||||
|
||||
const int kZlibBaseDist[D_CODES] = {
|
||||
0, 1, 2, 3, 4, 6, 8, 12, 16, 24,
|
||||
32, 48, 64, 96, 128, 192, 256, 384, 512, 768,
|
||||
1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576,
|
||||
};
|
1105
third_party/zlib/trees.c
vendored
Normal file
1105
third_party/zlib/trees.c
vendored
Normal file
File diff suppressed because it is too large
Load diff
91
third_party/zlib/uncompr.c
vendored
Normal file
91
third_party/zlib/uncompr.c
vendored
Normal file
|
@ -0,0 +1,91 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=4 sts=4 sw=4 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 1995-2003,2010,2014,2016 Jean-loup Gailly and Mark Adler │
|
||||
│ Use of this source code is governed by the BSD-style licenses that can │
|
||||
│ be found in the third_party/zlib/LICENSE file. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "third_party/zlib/zlib.h"
|
||||
|
||||
asm(".ident\t\"\\n\\n\
|
||||
zlib (zlib License)\\n\
|
||||
Copyright 1995-2017 Jean-loup Gailly and Mark Adler\"");
|
||||
asm(".include \"libc/disclaimer.inc\"");
|
||||
|
||||
/**
|
||||
* Decompresses the source buffer into the destination buffer. *sourceLen is
|
||||
* the byte length of the source buffer. Upon entry, *destLen is the total size
|
||||
* of the destination buffer, which must be large enough to hold the entire
|
||||
* uncompressed data. (The size of the uncompressed data must have been saved
|
||||
* previously by the compressor and transmitted to the decompressor by some
|
||||
* mechanism outside the scope of this compression library.) Upon exit,
|
||||
* *destLen is the size of the decompressed data and *sourceLen is the number
|
||||
* of source bytes consumed. Upon return, source + *sourceLen points to the
|
||||
* first unused input byte.
|
||||
*
|
||||
* uncompress returns Z_OK if success, Z_MEM_ERROR if there was not enough
|
||||
* memory, Z_BUF_ERROR if there was not enough room in the output buffer, or
|
||||
* Z_DATA_ERROR if the input data was corrupted, including if the input data is
|
||||
* an incomplete zlib stream.
|
||||
*/
|
||||
int uncompress2(Bytef *dest, uLongf *destLen, const Bytef *source,
|
||||
uLong *sourceLen) {
|
||||
z_stream stream;
|
||||
int err;
|
||||
const uInt max = (uInt)-1;
|
||||
uLong len, left;
|
||||
Byte buf[1]; /* for detection of incomplete stream when *destLen == 0 */
|
||||
|
||||
len = *sourceLen;
|
||||
if (*destLen) {
|
||||
left = *destLen;
|
||||
*destLen = 0;
|
||||
} else {
|
||||
left = 1;
|
||||
dest = buf;
|
||||
}
|
||||
|
||||
stream.next_in = (const Bytef *)source;
|
||||
stream.avail_in = 0;
|
||||
stream.zalloc = (alloc_func)0;
|
||||
stream.zfree = (free_func)0;
|
||||
stream.opaque = (voidpf)0;
|
||||
|
||||
err = inflateInit(&stream);
|
||||
if (err != Z_OK) return err;
|
||||
|
||||
stream.next_out = dest;
|
||||
stream.avail_out = 0;
|
||||
|
||||
do {
|
||||
if (stream.avail_out == 0) {
|
||||
stream.avail_out = left > (uLong)max ? max : (uInt)left;
|
||||
left -= stream.avail_out;
|
||||
}
|
||||
if (stream.avail_in == 0) {
|
||||
stream.avail_in = len > (uLong)max ? max : (uInt)len;
|
||||
len -= stream.avail_in;
|
||||
}
|
||||
err = inflate(&stream, Z_NO_FLUSH);
|
||||
} while (err == Z_OK);
|
||||
|
||||
*sourceLen -= len + stream.avail_in;
|
||||
if (dest != buf)
|
||||
*destLen = stream.total_out;
|
||||
else if (stream.total_out && err == Z_BUF_ERROR)
|
||||
left = 1;
|
||||
|
||||
inflateEnd(&stream);
|
||||
return err == Z_STREAM_END
|
||||
? Z_OK
|
||||
: err == Z_NEED_DICT
|
||||
? Z_DATA_ERROR
|
||||
: err == Z_BUF_ERROR && left + stream.avail_out
|
||||
? Z_DATA_ERROR
|
||||
: err;
|
||||
}
|
||||
|
||||
int uncompress(Bytef *dest, uLongf *destLen, const Bytef *source,
|
||||
uLong sourceLen) {
|
||||
return uncompress2(dest, destLen, source, &sourceLen);
|
||||
}
|
28
third_party/zlib/zalloc.c
vendored
Normal file
28
third_party/zlib/zalloc.c
vendored
Normal file
|
@ -0,0 +1,28 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/bits/bits.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "third_party/zlib/zutil.h"
|
||||
|
||||
void *zcalloc(void *opaque, unsigned items, unsigned size) {
|
||||
return weaken(malloc)(items * size);
|
||||
}
|
||||
|
||||
void zcfree(void *opaque, void *ptr) { weaken(free)(ptr); }
|
25
third_party/zlib/zconf.h
vendored
Normal file
25
third_party/zlib/zconf.h
vendored
Normal file
|
@ -0,0 +1,25 @@
|
|||
#ifndef COSMOPOLITAN_THIRD_PARTY_ZLIB_ZCONF_H_
|
||||
#define COSMOPOLITAN_THIRD_PARTY_ZLIB_ZCONF_H_
|
||||
|
||||
#define STDC
|
||||
#define STDC99
|
||||
#define MAX_MEM_LEVEL 9
|
||||
#define DEF_MEM_LEVEL 8
|
||||
#define MAX_WBITS 15 /* 32K LZ77 window */
|
||||
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
|
||||
typedef unsigned char Byte;
|
||||
typedef unsigned int uInt; /* 16 bits or more */
|
||||
typedef unsigned long uLong; /* 32 bits or more */
|
||||
typedef Byte Bytef;
|
||||
typedef char charf;
|
||||
typedef int intf;
|
||||
typedef uInt uIntf;
|
||||
typedef uLong uLongf;
|
||||
typedef void const *voidpc;
|
||||
typedef void *voidpf;
|
||||
typedef void *voidp;
|
||||
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_THIRD_PARTY_ZLIB_ZCONF_H_ */
|
1748
third_party/zlib/zlib.h
vendored
Normal file
1748
third_party/zlib/zlib.h
vendored
Normal file
File diff suppressed because it is too large
Load diff
72
third_party/zlib/zlib.mk
vendored
Normal file
72
third_party/zlib/zlib.mk
vendored
Normal file
|
@ -0,0 +1,72 @@
|
|||
#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
|
||||
#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘
|
||||
|
||||
PKGS += THIRD_PARTY_ZLIB
|
||||
|
||||
THIRD_PARTY_ZLIB_ARTIFACTS += THIRD_PARTY_ZLIB_A
|
||||
THIRD_PARTY_ZLIB = $(THIRD_PARTY_ZLIB_A_DEPS) $(THIRD_PARTY_ZLIB_A)
|
||||
THIRD_PARTY_ZLIB_A = o/$(MODE)/third_party/zlib/zlib.a
|
||||
THIRD_PARTY_ZLIB_A_FILES := $(wildcard third_party/zlib/*)
|
||||
THIRD_PARTY_ZLIB_A_HDRS = third_party/zlib/zlib.h
|
||||
THIRD_PARTY_ZLIB_A_HDRS_ALL = $(filter %.h,$(THIRD_PARTY_ZLIB_A_FILES))
|
||||
THIRD_PARTY_ZLIB_A_SRCS_S = $(filter %.S,$(THIRD_PARTY_ZLIB_A_FILES))
|
||||
THIRD_PARTY_ZLIB_A_SRCS_C = $(filter %.c,$(THIRD_PARTY_ZLIB_A_FILES))
|
||||
|
||||
THIRD_PARTY_ZLIB_A_SRCS = \
|
||||
$(THIRD_PARTY_ZLIB_A_SRCS_S) \
|
||||
$(THIRD_PARTY_ZLIB_A_SRCS_C)
|
||||
|
||||
THIRD_PARTY_ZLIB_A_OBJS = \
|
||||
$(THIRD_PARTY_ZLIB_A_SRCS:%=o/$(MODE)/%.zip.o) \
|
||||
$(THIRD_PARTY_ZLIB_A_SRCS_S:%.S=o/$(MODE)/%.o) \
|
||||
$(THIRD_PARTY_ZLIB_A_SRCS_C:%.c=o/$(MODE)/%.o)
|
||||
|
||||
THIRD_PARTY_ZLIB_A_CHECKS = \
|
||||
$(THIRD_PARTY_ZLIB_A).pkg \
|
||||
$(THIRD_PARTY_ZLIB_A_HDRS_ALL:%=o/$(MODE)/%.ok)
|
||||
|
||||
THIRD_PARTY_ZLIB_A_DIRECTDEPS = \
|
||||
LIBC_STUBS \
|
||||
LIBC_NEXGEN32E
|
||||
|
||||
THIRD_PARTY_ZLIB_A_DEPS := \
|
||||
$(call uniq,$(foreach x,$(THIRD_PARTY_ZLIB_A_DIRECTDEPS),$($(x))))
|
||||
|
||||
$(THIRD_PARTY_ZLIB_A): \
|
||||
third_party/zlib/ \
|
||||
$(THIRD_PARTY_ZLIB_A).pkg \
|
||||
$(THIRD_PARTY_ZLIB_A_OBJS)
|
||||
|
||||
$(THIRD_PARTY_ZLIB_A).pkg: \
|
||||
$(THIRD_PARTY_ZLIB_A_OBJS) \
|
||||
$(foreach x,$(THIRD_PARTY_ZLIB_A_DIRECTDEPS),$($(x)_A).pkg)
|
||||
|
||||
o/$(MODE)/third_party/zlib/adler32simd.o: \
|
||||
OVERRIDE_CFLAGS += \
|
||||
-mssse3
|
||||
|
||||
o/$(MODE)/third_party/zlib/crcfold.o: \
|
||||
OVERRIDE_CFLAGS += \
|
||||
-mpclmul \
|
||||
-mssse3
|
||||
|
||||
o/$(MODE)/third_party/zlib/deflate.o \
|
||||
o/$(MODE)/third_party/zlib/inflate.o \
|
||||
o/$(MODE)/third_party/zlib/adler32.o: \
|
||||
OVERRIDE_CFLAGS += \
|
||||
-ffunction-sections \
|
||||
-fdata-sections
|
||||
|
||||
THIRD_PARTY_ZLIB_LIBS = $(foreach x,$(THIRD_PARTY_ZLIB_ARTIFACTS),$($(x)))
|
||||
THIRD_PARTY_ZLIB_SRCS = $(foreach x,$(THIRD_PARTY_ZLIB_ARTIFACTS),$($(x)_SRCS))
|
||||
THIRD_PARTY_ZLIB_HDRS = $(foreach x,$(THIRD_PARTY_ZLIB_ARTIFACTS),$($(x)_HDRS))
|
||||
THIRD_PARTY_ZLIB_HDRS_ALL = $(foreach x,$(THIRD_PARTY_ZLIB_ARTIFACTS),$($(x)_HDRS_ALL))
|
||||
THIRD_PARTY_ZLIB_BINS = $(foreach x,$(THIRD_PARTY_ZLIB_ARTIFACTS),$($(x)_BINS))
|
||||
THIRD_PARTY_ZLIB_CHECKS = $(foreach x,$(THIRD_PARTY_ZLIB_ARTIFACTS),$($(x)_CHECKS))
|
||||
THIRD_PARTY_ZLIB_OBJS = $(foreach x,$(THIRD_PARTY_ZLIB_ARTIFACTS),$($(x)_OBJS))
|
||||
$(THIRD_PARTY_ZLIB_OBJS): $(BUILD_FILES) third_party/zlib/zlib.mk
|
||||
|
||||
.PHONY: o/$(MODE)/third_party/zlib
|
||||
o/$(MODE)/third_party/zlib: \
|
||||
$(THIRD_PARTY_ZLIB_A) \
|
||||
$(THIRD_PARTY_ZLIB_CHECKS)
|
128
third_party/zlib/zutil.c
vendored
Normal file
128
third_party/zlib/zutil.c
vendored
Normal file
|
@ -0,0 +1,128 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=4 sts=4 sw=4 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 1995-2017 Jean-loup Gailly │
|
||||
│ Use of this source code is governed by the BSD-style licenses that can │
|
||||
│ be found in the third_party/zlib/LICENSE file. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/mem/mem.h"
|
||||
#include "third_party/zlib/zutil.h"
|
||||
|
||||
asm(".ident\t\"\\n\\n\
|
||||
zlib (zlib License)\\n\
|
||||
Copyright 1995-2017 Jean-loup Gailly and Mark Adler\"");
|
||||
asm(".include \"libc/disclaimer.inc\"");
|
||||
|
||||
const char *const z_errmsg[10] = {
|
||||
(const char *)"need dictionary", /* Z_NEED_DICT 2 */
|
||||
(const char *)"stream end", /* Z_STREAM_END 1 */
|
||||
(const char *)"", /* Z_OK 0 */
|
||||
(const char *)"file error", /* Z_ERRNO (-1) */
|
||||
(const char *)"stream error", /* Z_STREAM_ERROR (-2) */
|
||||
(const char *)"data error", /* Z_DATA_ERROR (-3) */
|
||||
(const char *)"insufficient memory", /* Z_MEM_ERROR (-4) */
|
||||
(const char *)"buffer error", /* Z_BUF_ERROR (-5) */
|
||||
(const char *)"", /* Z_VERSION_ERROR (-6) */
|
||||
(const char *)"",
|
||||
};
|
||||
|
||||
const char *zlibVersion() { return ZLIB_VERSION; }
|
||||
|
||||
uLong zlibCompileFlags() {
|
||||
uLong flags;
|
||||
flags = 0;
|
||||
switch ((int)(sizeof(uInt))) {
|
||||
case 2:
|
||||
break;
|
||||
case 4:
|
||||
flags += 1;
|
||||
break;
|
||||
case 8:
|
||||
flags += 2;
|
||||
break;
|
||||
default:
|
||||
flags += 3;
|
||||
}
|
||||
switch ((int)(sizeof(uLong))) {
|
||||
case 2:
|
||||
break;
|
||||
case 4:
|
||||
flags += 1 << 2;
|
||||
break;
|
||||
case 8:
|
||||
flags += 2 << 2;
|
||||
break;
|
||||
default:
|
||||
flags += 3 << 2;
|
||||
}
|
||||
switch ((int)(sizeof(voidpf))) {
|
||||
case 2:
|
||||
break;
|
||||
case 4:
|
||||
flags += 1 << 4;
|
||||
break;
|
||||
case 8:
|
||||
flags += 2 << 4;
|
||||
break;
|
||||
default:
|
||||
flags += 3 << 4;
|
||||
}
|
||||
switch ((int)(sizeof(int64_t))) {
|
||||
case 2:
|
||||
break;
|
||||
case 4:
|
||||
flags += 1 << 6;
|
||||
break;
|
||||
case 8:
|
||||
flags += 2 << 6;
|
||||
break;
|
||||
default:
|
||||
flags += 3 << 6;
|
||||
}
|
||||
#ifdef ZLIB_DEBUG
|
||||
flags += 1 << 8;
|
||||
#endif
|
||||
#if defined(ASMV) || defined(ASMINF)
|
||||
flags += 1 << 9;
|
||||
#endif
|
||||
#ifdef ZLIB_WINAPI
|
||||
flags += 1 << 10;
|
||||
#endif
|
||||
#ifdef BUILDFIXED
|
||||
flags += 1 << 12;
|
||||
#endif
|
||||
#ifdef DYNAMIC_CRC_TABLE
|
||||
flags += 1 << 13;
|
||||
#endif
|
||||
#ifdef NO_GZCOMPRESS
|
||||
flags += 1L << 16;
|
||||
#endif
|
||||
#ifdef NO_GZIP
|
||||
flags += 1L << 17;
|
||||
#endif
|
||||
#ifdef PKZIP_BUG_WORKAROUND
|
||||
flags += 1L << 20;
|
||||
#endif
|
||||
#ifdef FASTEST
|
||||
flags += 1L << 21;
|
||||
#endif
|
||||
return flags;
|
||||
}
|
||||
|
||||
#ifdef ZLIB_DEBUG
|
||||
#ifndef verbose
|
||||
#define verbose 0
|
||||
#endif
|
||||
int z_verbose hidden = verbose;
|
||||
|
||||
void z_error(char *m) {
|
||||
fprintf(stderr, "%s\n", m);
|
||||
exit(1);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Exported to allow conversion of error code to string for compress()
|
||||
* and uncompress()
|
||||
*/
|
||||
const char *zError(int err) { return ERR_MSG(err); }
|
100
third_party/zlib/zutil.h
vendored
Normal file
100
third_party/zlib/zutil.h
vendored
Normal file
|
@ -0,0 +1,100 @@
|
|||
#ifndef ZUTIL_H
|
||||
#define ZUTIL_H
|
||||
#include "third_party/zlib/zlib.h"
|
||||
|
||||
/* default windowBits for decompression. MAX_WBITS is for compression only */
|
||||
#ifndef DEF_WBITS
|
||||
#define DEF_WBITS MAX_WBITS
|
||||
#endif
|
||||
|
||||
/* default memLevel */
|
||||
|
||||
/* The three kinds of block type */
|
||||
#define STORED_BLOCK 0
|
||||
#define STATIC_TREES 1
|
||||
#define DYN_TREES 2
|
||||
|
||||
/* The minimum and maximum match lengths */
|
||||
#define MIN_MATCH 3
|
||||
#define MAX_MATCH 258
|
||||
|
||||
#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */
|
||||
|
||||
#define OS_CODE 3 /* assume Unix */
|
||||
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
#ifndef local
|
||||
#define local static
|
||||
#endif
|
||||
/* since "static" is used to mean two completely different things in C, we
|
||||
define "local" for the non-static meaning of "static", for readability
|
||||
(compile with -Dlocal if your debugger can't find static symbols) */
|
||||
|
||||
extern const char *const z_errmsg[10]; /* indexed by 2-zlib_error */
|
||||
/* (size given to avoid silly warnings with Visual C++) */
|
||||
|
||||
#define ERR_MSG(err) z_errmsg[Z_NEED_DICT - (err)]
|
||||
|
||||
#define ERR_RETURN(strm, err) return (strm->msg = ERR_MSG(err), (err))
|
||||
/* To be used only when the state is known to be valid */
|
||||
|
||||
#ifndef F_OPEN
|
||||
#define F_OPEN(name, mode) fopen((name), (mode))
|
||||
#endif
|
||||
|
||||
/* Diagnostic functions */
|
||||
#ifdef ZLIB_DEBUG
|
||||
#include "libc/stdio/stdio.h"
|
||||
extern int z_verbose hidden;
|
||||
extern void z_error(char *m) hidden;
|
||||
#define Assert(cond, msg) \
|
||||
{ \
|
||||
if (!(cond)) z_error(msg); \
|
||||
}
|
||||
#define Trace(x) \
|
||||
{ \
|
||||
if (z_verbose >= 0) fprintf x; \
|
||||
}
|
||||
#define Tracev(x) \
|
||||
{ \
|
||||
if (z_verbose > 0) fprintf x; \
|
||||
}
|
||||
#define Tracevv(x) \
|
||||
{ \
|
||||
if (z_verbose > 1) fprintf x; \
|
||||
}
|
||||
#define Tracec(c, x) \
|
||||
{ \
|
||||
if (z_verbose > 0 && (c)) fprintf x; \
|
||||
}
|
||||
#define Tracecv(c, x) \
|
||||
{ \
|
||||
if (z_verbose > 1 && (c)) fprintf x; \
|
||||
}
|
||||
#else
|
||||
#define Assert(cond, msg)
|
||||
#define Trace(x)
|
||||
#define Tracev(x)
|
||||
#define Tracevv(x)
|
||||
#define Tracec(c, x)
|
||||
#define Tracecv(c, x)
|
||||
#endif
|
||||
|
||||
#define ZALLOC(strm, items, size) \
|
||||
(*((strm)->zalloc))((strm)->opaque, (items), (size))
|
||||
#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr))
|
||||
#define TRY_FREE(s, p) \
|
||||
{ \
|
||||
if (p) ZFREE(s, p); \
|
||||
}
|
||||
|
||||
/* Reverse the bytes in a 32-bit value */
|
||||
#define ZSWAP32(q) \
|
||||
((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + (((q)&0xff00) << 8) + \
|
||||
(((q)&0xff) << 24))
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* ZUTIL_H */
|
Loading…
Add table
Add a link
Reference in a new issue