Initial import

This commit is contained in:
Justine Tunney 2020-06-15 07:18:57 -07:00
commit c91b3c5006
14915 changed files with 590219 additions and 0 deletions

58
third_party/zlib/LICENSE vendored Normal file
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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

File diff suppressed because it is too large Load diff

321
third_party/zlib/deflate.h vendored Normal file
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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

File diff suppressed because it is too large Load diff

144
third_party/zlib/inflate.h vendored Normal file
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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

File diff suppressed because it is too large Load diff

91
third_party/zlib/uncompr.c vendored Normal file
View 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
View 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
View 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

File diff suppressed because it is too large Load diff

72
third_party/zlib/zlib.mk vendored Normal file
View 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
View 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
View 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 */