29#if !defined(__cplusplus) && (!defined(__STDC_VERSION__) || __STDC_VERSION__ < 201112L)
30#error "libzxc requires C11 or later (MSVC: /std:c11)"
37#include "../../include/zxc_buffer.h"
38#include "../../include/zxc_constants.h"
39#include "../../include/zxc_error.h"
40#include "../../include/zxc_seekable.h"
61#if !defined(__cplusplus) && !defined(__STDC_NO_ATOMICS__)
63#define ZXC_ATOMIC _Atomic
64#define ZXC_USE_C11_ATOMICS 1
66#define ZXC_ATOMIC volatile
67#define ZXC_USE_C11_ATOMICS 0
98#ifndef ZXC_DISABLE_SIMD
99#if defined(__x86_64__) || defined(_M_X64) || defined(__i386__) || defined(_M_IX86)
100#include <immintrin.h>
101#include <nmmintrin.h>
102#if defined(__AVX512F__) && defined(__AVX512BW__)
103#ifndef ZXC_USE_AVX512
104#define ZXC_USE_AVX512
112#if defined(__SSE2__) || defined(_M_X64) || (defined(_M_IX86_FP) && _M_IX86_FP >= 2)
117#elif (defined(__ARM_NEON) || defined(__ARM_NEON__) || defined(_M_ARM64) || \
118 defined(ZXC_USE_NEON32) || defined(ZXC_USE_NEON64))
119#if !defined(_MSC_VER)
123#if defined(__aarch64__) || defined(_M_ARM64)
124#ifndef ZXC_USE_NEON64
125#define ZXC_USE_NEON64
128#ifndef ZXC_USE_NEON32
129#define ZXC_USE_NEON32
143#if defined(__GNUC__) || defined(__clang__)
148#define LIKELY(x) (__builtin_expect(!!(x), 1))
154#define UNLIKELY(x) (__builtin_expect(!!(x), 0))
159#define RESTRICT __restrict__
165#define ZXC_PREFETCH_READ(ptr) __builtin_prefetch((const void*)(ptr), 0, 3)
170#define ZXC_MEMCPY(dst, src, n) __builtin_memcpy(dst, src, n)
175#define ZXC_MEMSET(dst, val, n) __builtin_memset(dst, val, n)
181#define ZXC_ALIGN(x) __attribute__((aligned(x)))
186#define ZXC_ALWAYS_INLINE inline __attribute__((always_inline))
191#define ZXC_NOINLINE __attribute__((__noinline__))
199#define ZXC_COLD __attribute__((cold))
201#elif defined(_MSC_VER)
203#if defined(_M_IX86) || defined(_M_X64) || defined(_M_AMD64)
204#include <xmmintrin.h>
205#define ZXC_PREFETCH_READ(ptr) _mm_prefetch((const char*)(ptr), _MM_HINT_T0)
207#define ZXC_PREFETCH_READ(ptr) __prefetch((const void*)(ptr))
210#define UNLIKELY(x) (x)
211#define RESTRICT __restrict
212#pragma intrinsic(memcpy, memset)
213#define ZXC_MEMCPY(dst, src, n) memcpy(dst, src, n)
214#define ZXC_MEMSET(dst, val, n) memset(dst, val, n)
220#define ZXC_ALIGN(x) __declspec(align(x))
225#define ZXC_ALWAYS_INLINE __forceinline
230#define ZXC_NOINLINE __declspec(noinline)
233#pragma intrinsic(_BitScanReverse)
236#define UNLIKELY(x) (x)
238#define ZXC_PREFETCH_READ(ptr)
239#define ZXC_MEMCPY(dst, src, n) memcpy(dst, src, n)
240#define ZXC_MEMSET(dst, val, n) memset(dst, val, n)
245#define ZXC_ALWAYS_INLINE inline
257#define ZXC_ALIGN(x) _Alignas(x)
272#ifndef ZXC_LITTLE_ENDIAN
273#if defined(_WIN32) || defined(__LITTLE_ENDIAN__) || \
274 (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
275#define ZXC_LITTLE_ENDIAN
276#elif defined(__BIG_ENDIAN__) || (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
277#define ZXC_BIG_ENDIAN
279#warning "Endianness not detected, defaulting to little-endian"
280#define ZXC_LITTLE_ENDIAN
291#if defined(__GNUC__) || defined(__clang__)
292#define ZXC_BSWAP16(x) __builtin_bswap16(x)
293#define ZXC_BSWAP32(x) __builtin_bswap32(x)
294#define ZXC_BSWAP64(x) __builtin_bswap64(x)
295#elif defined(_MSC_VER)
296#define ZXC_BSWAP16(x) _byteswap_ushort(x)
297#define ZXC_BSWAP32(x) _byteswap_ulong(x)
298#define ZXC_BSWAP64(x) _byteswap_uint64(x)
300#define ZXC_BSWAP16(x) ((uint16_t)(((x) >> 8) | ((x) << 8)))
301#define ZXC_BSWAP32(x) \
302 ((uint32_t)(((x) >> 24) | (((x) >> 8) & 0xFF00) | (((x) << 8) & 0xFF0000) | ((x) << 24)))
303#define ZXC_BSWAP64(x) \
304 ((uint64_t)(((uint64_t)ZXC_BSWAP32((uint32_t)(x)) << 32) | ZXC_BSWAP32((uint32_t)((x) >> 32))))
322 for (
size_t i = 0; i < n && i <
sizeof(magic); i++)
323 if (p[i] != magic[i])
return 0;
328#define ZXC_FILE_FORMAT_VERSION 9
331#define ZXC_PAD_SIZE 32
345#define ZXC_BLOCK_LIT_SLACK 32
357#define ZXC_DECOMPRESS_TAIL_PAD (ZXC_PAD_SIZE * 66)
359#define ZXC_CACHE_LINE_SIZE 64
361#define ZXC_ALIGNMENT_MASK ((size_t)ZXC_CACHE_LINE_SIZE - 1)
363#define ZXC_ALIGN_CL(x) (((x) + ZXC_ALIGNMENT_MASK) & ~(size_t)ZXC_ALIGNMENT_MASK)
365 "ZXC_CACHE_LINE_SIZE must be a power of two");
372#define ZXC_BITMAP_WORDS(n_bits) (((n_bits) + 63) / 64)
375#define ZXC_FILE_FLAG_HAS_CHECKSUM 0x80U
377#define ZXC_FILE_FLAG_HAS_DICTIONARY 0x40U
380#define ZXC_FILE_FLAG_HAS_SEEK_TABLE 0x20U
382#define ZXC_FILE_CHECKSUM_ALGO_MASK 0x0FU
386 "a file flag overlaps the checksum algorithm id");
393#define ZXC_DICT_VERSION 2
396#define ZXC_DICT_KGRAM_LEN ZXC_LZ_MIN_MATCH_LEN
398#define ZXC_DICT_HASH_BITS 16
400#define ZXC_DICT_MAX_SEGMENTS (1U << 16)
404#define ZXC_DICT_SAMPLE_TARGET (1U << 19)
406#define ZXC_DICT_HASH_SIZE (1U << ZXC_DICT_HASH_BITS)
408#define ZXC_DICT_HUF_TRAIN_BLOCK 4096U
411#define ZXC_DICT_HUF_SAMPLE_BUDGET (8U << 20)
414#define ZXC_BLOCK_HEADER_SIZE 8
416#define ZXC_BLOCK_CHECKSUM_SIZE 4
418#define ZXC_GLO_HEADER_BINARY_SIZE 12
420#define ZXC_GHI_HEADER_BINARY_SIZE 12
422#define ZXC_GLO_DESC_MAX_SIZE (2 * sizeof(uint32_t))
432#define ZXC_BLOCK_FORMAT_OVERHEAD 68
435 "ZXC_BLOCK_FORMAT_OVERHEAD must cover sub-header, descriptors and slack");
438#define ZXC_CHECKSUM_RAPIDHASH 0
449#define ZXC_SEEK_GROUP 64U
451#define ZXC_SEEK_ANCHOR_SIZE 8U
453#define ZXC_SEEK_SIZE_ENTRY 4U
455#define ZXC_SEEK_GROUP_BYTES (ZXC_SEEK_ANCHOR_SIZE + ZXC_SEEK_GROUP * ZXC_SEEK_SIZE_ENTRY)
476#if defined(_MSC_VER) && !defined(__clang__) && (defined(_M_ARM64) || defined(_M_ARM64EC))
480 const volatile uint64_t t = table_bytes;
481 return (uint32_t)(t ^ (t >> 32));
483 return (uint32_t)(table_bytes ^ (table_bytes >> 32));
493#define ZXC_TOKEN_LIT_BITS 4
495#define ZXC_TOKEN_ML_BITS 4
497#define ZXC_TOKEN_LL_MASK ((1U << ZXC_TOKEN_LIT_BITS) - 1)
499#define ZXC_TOKEN_ML_MASK ((1U << ZXC_TOKEN_ML_BITS) - 1)
501 "the GLO decoder reads its tokens as two nibbles");
508#define ZXC_SEQ_LL_BITS 8
510#define ZXC_SEQ_ML_BITS 8
512#define ZXC_SEQ_OFF_BITS 16
514#define ZXC_SEQ_LL_MASK ((1U << ZXC_SEQ_LL_BITS) - 1)
516#define ZXC_SEQ_ML_MASK ((1U << ZXC_SEQ_ML_BITS) - 1)
518#define ZXC_SEQ_OFF_MASK ((1U << ZXC_SEQ_OFF_BITS) - 1)
520 "a GHI sequence is one 32-bit word");
526#define ZXC_LIT_RLE_FLAG 0x80U
528#define ZXC_LIT_LEN_MASK (ZXC_LIT_RLE_FLAG - 1)
543#define ZXC_LZ_HASH_BITS 15
545#define ZXC_LZ_HASH_SIZE (1U << ZXC_LZ_HASH_BITS)
547#define ZXC_LZ_WINDOW_SIZE (1U << 16)
549#define ZXC_LZ_WINDOW_MASK (ZXC_LZ_WINDOW_SIZE - 1U)
551#define ZXC_LZ_MIN_MATCH_LEN 5
560#define ZXC_MAX_VARINT_VALUE ((uint32_t)(ZXC_BLOCK_SIZE_MAX - 1U))
565 "ZXC_BLOCK_SIZE_DEFAULT must be a power of two within the block size range");
567 "ZXC_LZ_WINDOW_SIZE must be a power of two (ring mask)");
569 "chain_table holds window positions in 16 bits");
587 const uint8_t* p = *ptr;
588 if (UNLIKELY(p >= end))
return 0;
590 const uint32_t b0 = p[0];
593 if (LIKELY(b0 < 0x80)) {
599 if (LIKELY(b0 < 0xC0)) {
600 if (UNLIKELY(p + 1 >= end)) {
605 return (b0 & 0x3F) | ((uint32_t)p[1] << 6);
611 if (LIKELY(b0 < 0xE0)) {
612 if (UNLIKELY(p + 2 >= end)) {
617 return (b0 & 0x1F) | ((uint32_t)p[1] << 5) | ((uint32_t)p[2] << 13);
630#define ZXC_GLO_MAX_INLINE_OUT_PER_SEQ ((ZXC_TOKEN_LL_MASK - 1U) + ZXC_GLO_MAX_INLINE_ML)
633#define ZXC_GLO_INLINE_ML_CODE (ZXC_TOKEN_ML_MASK - 1U)
639#define ZXC_GLO_MAX_INLINE_ML (ZXC_GLO_INLINE_ML_CODE + ZXC_LZ_MIN_MATCH_LEN)
640#define ZXC_GHI_MAX_INLINE_OUT_PER_SEQ \
641 ((ZXC_SEQ_LL_MASK - 1U) + (ZXC_SEQ_ML_MASK - 1U) + ZXC_LZ_MIN_MATCH_LEN)
643#define ZXC_LZ_OFFSET_BIAS 1
645#define ZXC_LZ_MAX_DIST (ZXC_LZ_WINDOW_SIZE - 1)
648 "a biased offset must fit the 16-bit wire field");
650 "ZXC_DECOMPRESS_TAIL_PAD must hold a 4x GHI batch and its wild-copy overshoot");
660#define ZXC_LZ_MINDIST 32
667#define ZXC_LZ_MINDIST_PROBE_PER_KB 1024
668#define ZXC_LZ_MINDIST_PROBE_MIN 16
669#define ZXC_LZ_MINDIST_PROBE_MAX 64
677#define ZXC_LZ_MINDIST_MAX_SHORT_PCT 20
680#define ZXC_LZ_SEARCH_MARGIN (sizeof(uint64_t))
689#define ZXC_OPT_MATCH_COST_BASE ((uint32_t)(3U * CHAR_BIT))
692#define ZXC_OPT_LONG_MATCH_SKIP ((size_t)256)
694 "covered positions relax only the first two match cost classes");
699#define ZXC_OPT_LIT_SAMPLE_MIN 1024
709#define ZXC_HASH_GOLDEN64 0x9E3779B97F4A7C15ULL
711#define ZXC_HASH_XORSHIFT64 0x2545F4914F6CDD1DULL
713#define ZXC_HASH_MULT32 0x2D35182DU
715#define ZXC_HASH_MULT64 0xD2D84A61D2D84A61ULL
738#define ZXC_HUF_MAX_CODE_LEN_ULTRA 11
743#define ZXC_HUF_MAX_CODE_LEN_DENSITY 8
745#define ZXC_HUF_NUM_SYMBOLS 256
747 "the decoder accepts code lengths up to ZXC_HUF_MAX_CODE_LEN_ULTRA only");
749 "code lengths are packed one nibble per symbol");
752#define ZXC_PIVCO_MAX_NODES (2 * ZXC_HUF_NUM_SYMBOLS - 1)
755#define ZXC_PIVCO_NODE_SLOTS (ZXC_PIVCO_MAX_NODES + 1)
759#define ZXC_PIVCO_UNPACK_FLAT_SIMD_MAX 6
762#define ZXC_PIVCO_COVERED 0xFFU
804#define ZXC_RLE_MARGIN_SHIFT 5
808#define ZXC_HUF_MARGIN_SHIFT 5
825#define ZXC_HUF_NUDGE_LAMBDA_Q8 26
828#define ZXC_HUF_NUDGE_BITS_PERMIL 1015
831#define ZXC_HUF_NUDGE_MERGE_Q8 230
836#define ZXC_HUF_NUDGE_DEEP_FLAT_PENALTY 24
840#define ZXC_HUF_NUDGE_LEVEL_COST 64
862#define ZXC_SS_TAX(n, prem_q8) (((size_t)(n) * (size_t)(prem_q8)) >> 8)
911#define ZXC_HUF_MIN_LITERALS 139
930#define ZXC_OPTS_DICT_SIZE(o) (((o) && (o)->dict) ? (o)->dict_size : (size_t)0)
932#define ZXC_OPTS_DICT_HUF(o) \
933 (((o) && (o)->dict && (o)->dict_size > 0) ? (const uint8_t*)(o)->dict_huf : NULL)
936#define ZXC_OPTS_LEVEL(o, dflt) zxc_level_clamp(((o) && (o)->level > 0) ? (o)->level : (dflt))
938#define ZXC_OPTS_BLOCK_SIZE(o, dflt) (((o) && (o)->block_size > 0) ? (o)->block_size : (dflt))
950#define ZXC_GLO_SPLIT_CTX_BITS 8
953#define ZXC_GLO_SPLIT_MIN_MISPREDICT_PCT 80
996#define ZXC_HUF_PM_LEVEL_BOUND (2 * ZXC_HUF_NUM_SYMBOLS)
1002#define ZXC_HUF_BUILD_SCRATCH_SIZE \
1003 ((size_t)ZXC_HUF_MAX_CODE_LEN_ULTRA * (size_t)ZXC_HUF_PM_LEVEL_BOUND * \
1004 sizeof(zxc_huf_pm_item_t) + \
1005 8U + (size_t)ZXC_HUF_MAX_CODE_LEN_ULTRA * sizeof(int) + 8U + \
1006 (size_t)ZXC_HUF_MAX_CODE_LEN_ULTRA * (size_t)ZXC_HUF_PM_LEVEL_BOUND * \
1007 sizeof(zxc_huf_pm_frame_t))
1011#define ZXC_HUF_NUDGE_DP_M 64
1031#define ZXC_HUF_NUDGE_SCRATCH_OFF ZXC_ALIGN_CL(ZXC_HUF_BUILD_SCRATCH_SIZE)
1033#define ZXC_HUF_NUDGE_SCRATCH_SIZE (ZXC_HUF_NUDGE_SCRATCH_OFF + sizeof(zxc_huf_nudge_ws_t))
1042 size_t* RESTRICT sz_pl,
size_t* RESTRICT sz_po,
1043 size_t* RESTRICT sz_bm) {
1044 *sz_dp =
ZXC_ALIGN_CL((chunk_size + 1) *
sizeof(uint32_t));
1045 *sz_pl =
ZXC_ALIGN_CL((chunk_size + 1) *
sizeof(uint16_t));
1046 *sz_po =
ZXC_ALIGN_CL((chunk_size + 1) *
sizeof(uint16_t));
1061 unsigned long index;
1062 return (v == 0) ? 0 : (_BitScanReverse(&index, v) ? index : 0);
1064 return (v == 0) ? 0 : (uint32_t)(31 - __builtin_clz(v));
1074 uint64_t x = (uint64_t)v - 1;
1082 const size_t bs = (size_t)x;
1175 {64, 256, 0, 0, 0, 1, 8, 1, 0}
1202 ZXC_BLOCK_SEK = 254,
1225 ZXC_SECTION_ENCODING_RAW = 0,
1226 ZXC_SECTION_ENCODING_RLE = 1,
1227 ZXC_SECTION_ENCODING_HUFFMAN = 2,
1228 ZXC_SECTION_ENCODING_HUFFMAN_DICT = 3
1281 ZXC_MEMCPY(&v, p,
sizeof(v));
1282#ifdef ZXC_BIG_ENDIAN
1283 return ZXC_BSWAP16(v);
1300 ZXC_MEMCPY(&v, p,
sizeof(v));
1301#ifdef ZXC_BIG_ENDIAN
1302 return ZXC_BSWAP32(v);
1321 const size_t size) {
1324 if (size < d_max +
sizeof(uint32_t))
return 1;
1327 if (want < ZXC_LZ_MINDIST_PROBE_MIN) want = ZXC_LZ_MINDIST_PROBE_MIN;
1328 if (want > ZXC_LZ_MINDIST_PROBE_MAX) want = ZXC_LZ_MINDIST_PROBE_MAX;
1329 size_t stride = size / want;
1330 if (stride < d_max) stride = d_max;
1332 const size_t planned = (size -
sizeof(uint32_t) - d_max) / stride + 1;
1337 for (
size_t i = d_max; i +
sizeof(uint32_t) <= size; i += stride) {
1338 const uint32_t cur =
zxc_le32(blk + i);
1340 for (
size_t d = 1; d < d_max; d++) {
1341 if (
zxc_le32(blk + i - d) == cur) {
1346 if (hits * 100U > bar)
return 1;
1347 if ((hits + (planned - samples)) * 100U <= bar)
return 0;
1349 return hits * 100U > bar;
1363 ZXC_MEMCPY(&v, p,
sizeof(v));
1364#ifdef ZXC_BIG_ENDIAN
1365 return ZXC_BSWAP64(v);
1381#ifdef ZXC_BIG_ENDIAN
1382 const uint16_t s = ZXC_BSWAP16(v);
1383 ZXC_MEMCPY(p, &s,
sizeof(s));
1385 ZXC_MEMCPY(p, &v,
sizeof(v));
1399#ifdef ZXC_BIG_ENDIAN
1400 const uint32_t s = ZXC_BSWAP32(v);
1401 ZXC_MEMCPY(p, &s,
sizeof(s));
1403 ZXC_MEMCPY(p, &v,
sizeof(v));
1417#ifdef ZXC_BIG_ENDIAN
1418 const uint64_t s = ZXC_BSWAP64(v);
1419 ZXC_MEMCPY(p, &s,
sizeof(s));
1421 ZXC_MEMCPY(p, &v,
sizeof(v));
1440 return (uint8_t)(h >> 56);
1482#if defined(ZXC_USE_AVX2) || defined(ZXC_USE_AVX512) || defined(ZXC_USE_SSE2)
1484 _mm_storeu_si128((__m128i*)dst, _mm_loadu_si128((
const __m128i*)src));
1485#elif defined(ZXC_USE_NEON64) || defined(ZXC_USE_NEON32)
1486 vst1q_u8((uint8_t*)dst, vld1q_u8((
const uint8_t*)src));
1488 ZXC_MEMCPY(dst, src, 16);
1501#if defined(ZXC_USE_AVX2) || defined(ZXC_USE_AVX512)
1503 _mm256_storeu_si256((__m256i*)dst, _mm256_loadu_si256((
const __m256i*)src));
1504#elif defined(ZXC_USE_SSE2)
1505 const __m128i a = _mm_loadu_si128((
const __m128i*)src);
1506 const __m128i b = _mm_loadu_si128((
const __m128i*)((
const uint8_t*)src + 16));
1507 _mm_storeu_si128((__m128i*)dst, a);
1508 _mm_storeu_si128((__m128i*)((uint8_t*)dst + 16), b);
1509#elif defined(ZXC_USE_NEON64) || defined(ZXC_USE_NEON32)
1510 const uint8x16_t a = vld1q_u8((
const uint8_t*)src);
1511 const uint8x16_t b = vld1q_u8((
const uint8_t*)src + 16);
1512 vst1q_u8((uint8_t*)dst, a);
1513 vst1q_u8((uint8_t*)dst + 16, b);
1515 ZXC_MEMCPY(dst, src, 32);
1529 if (x == 0)
return 32;
1530#if defined(__GNUC__) || defined(__clang__)
1531 return __builtin_ctz(x);
1532#elif defined(_MSC_VER)
1534 _BitScanForward(&r, x);
1538 static const int DeBruijn32[32] = {0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20,
1539 15, 25, 17, 4, 8, 31, 27, 13, 23, 21, 19,
1540 16, 7, 26, 12, 18, 6, 11, 5, 10, 9};
1541 return DeBruijn32[((uint32_t)((x & (0U - x)) * 0x077CB531U)) >> 27];
1555 if (x == 0)
return 64;
1556#if defined(__GNUC__) || defined(__clang__)
1557 return __builtin_ctzll(x);
1558#elif defined(_MSC_VER) && (defined(_M_X64) || defined(_M_ARM64))
1560 _BitScanForward64(&r, x);
1562#elif defined(_MSC_VER)
1565 const uint32_t lo = (uint32_t)x;
1566 if (_BitScanForward(&r, lo))
return (
int)r;
1567 _BitScanForward(&r, (uint32_t)(x >> 32));
1571 static const int Debruijn64[64] = {
1572 0, 1, 48, 2, 57, 49, 28, 3, 61, 58, 50, 42, 38, 29, 17, 4, 62, 55, 59, 36, 53, 51,
1573 43, 22, 45, 39, 33, 30, 24, 18, 12, 5, 63, 47, 56, 27, 60, 41, 37, 16, 54, 35, 52, 21,
1574 44, 32, 23, 11, 46, 26, 40, 15, 34, 20, 31, 10, 25, 14, 19, 9, 13, 8, 7, 6};
1575 return Debruijn64[((x & (0ULL - x)) * 0x03F79D71B4CA8B09ULL) >> 58];
1582 const size_t block_size) {
1585 if (UNLIKELY(!block_size))
return 0;
1586 const int s =
zxc_ctz32((uint32_t)block_size);
1587 return (total_decomp >> s) + ((total_decomp & (block_size - 1)) != 0);
1614 const uint64_t seed,
const uint8_t hash_method) {
1616 const uint64_t hash = rapidhash_withSeed(input, len, seed);
1618 return (uint32_t)(hash ^ (hash >> (
sizeof(uint32_t) * CHAR_BIT)));
1634 const uint32_t block_checksum) {
1637#if defined(__SIZEOF_INT128__)
1638 const __uint128_t r = (__uint128_t)a * b;
1639 return (uint64_t)r ^ (uint64_t)(r >> 64);
1641 const uint64_t alo = (uint32_t)a, ahi = a >> 32, blo = (uint32_t)b, bhi = b >> 32;
1642 const uint64_t lolo = alo * blo, lohi = alo * bhi, hilo = ahi * blo, hihi = ahi * bhi;
1643 const uint64_t cross = (lolo >> 32) + (uint32_t)lohi + (uint32_t)hilo;
1644 const uint64_t hi = hihi + (lohi >> 32) + (hilo >> 32) + (cross >> 32);
1645 const uint64_t lo = (cross << 32) | (uint32_t)lolo;
1666 const uint32_t tok_comp);
1683 uint32_t* RESTRICT tok_comp);
1734 void* RESTRICT scratch,
int max_code_len);
1768 void* RESTRICT scratch,
size_t scratch_cap,
int max_code_len);
1777void zxc_huf_nudge_cost(
const uint8_t* RESTRICT code_len,
const uint32_t* RESTRICT freq,
1778 uint64_t* RESTRICT bits, uint64_t* RESTRICT touches);
1821#define ZXC_PIVCO_SCRATCH_PAD 32
1825size_t zxc_huf_calc_size(
const uint32_t* RESTRICT freq,
const uint8_t* RESTRICT code_len,
1830 const uint32_t* RESTRICT freq,
const uint8_t* RESTRICT code_len,
1831 uint8_t* RESTRICT dst,
size_t dst_cap);
1836 uint32_t* RESTRICT codes, uint8_t* RESTRICT code_len);
1844 const uint32_t* RESTRICT freq,
const uint8_t* RESTRICT code_len,
1846 const uint32_t* RESTRICT codes, uint8_t* RESTRICT dst,
1852 uint8_t* RESTRICT dst,
size_t n, uint8_t* RESTRICT scratch);
1856 uint8_t* RESTRICT dst,
size_t n,
1964 const int checksum_enabled,
const size_t dict_size);
1995 const size_t dict_size);
2030 const size_t workspace_size,
const size_t chunk_size,
const int mode,
2031 const int level,
const int checksum_enabled,
const size_t dict_size,
2032 const int defer_entropy_scratch);
2072 const size_t src_sz, uint8_t* RESTRICT dst,
const size_t dst_cap,
2073 const uint64_t block_index);
2075 const size_t src_sz, uint8_t* RESTRICT dst,
2076 const size_t dst_cap,
const uint64_t block_index);
2079 const size_t src_sz, uint8_t* RESTRICT dst,
2080 const size_t dst_cap,
const uint64_t block_index);
2097 const size_t src_sz, uint8_t* RESTRICT dst,
const size_t dst_cap,
2098 const uint64_t block_index);
2102 void* RESTRICT dst,
size_t dst_capacity,
2144 const int has_checksum,
const uint32_t dict_id,
const int has_seek);
2167int zxc_read_file_header(
const uint8_t* RESTRICT src,
const size_t src_size,
size_t* out_block_size,
2168 int* out_has_checksum, uint32_t* out_dict_id,
int* out_has_seek);
2175 &chunk, NULL, NULL, NULL);
2236 size_t* footer_len);
2304 while (n <
sizeof(uint64_t) && (v >> (8 * n)) != 0) n++;
2324 const uint64_t src_size,
2325 const int checksum_enabled) {
2329 const uint64_t base = prefix + l.
skip + l.
nd + 1;
2345 const uint64_t src_size,
const uint64_t digest,
2346 const int checksum_enabled);
2363 uint64_t src_size, uint64_t* digest);
2379 uint64_t* compressed_size,
size_t* sizes_len);
2382#define ZXC_FOOTER_MAX_SIZE_WITH_DIGEST (ZXC_FILE_DIGEST_SIZE + ZXC_FILE_FOOTER_MAX_SIZE)
2385#define ZXC_FRAME_MIN_SIZE (ZXC_FILE_HEADER_SIZE + ZXC_BLOCK_HEADER_SIZE + ZXC_FILE_FOOTER_MIN_SIZE)
2407int zxc_read_frame_info(
const uint8_t* header,
const uint8_t* tail,
size_t tail_len, uint64_t total,
2413 ZXC_MEMCPY(info, got, info_size <
sizeof(*got) ? info_size :
sizeof(*got));
2433 const size_t chunk_size,
2434 const uint64_t comp_size) {
2476 uint64_t* sek_bytes);
2504 const uint32_t* RESTRICT sizes, uint32_t cnt);
struct zxc_cctx_s zxc_cctx
Opaque reusable compression context (see zxc_create_cctx).
#define ZXC_BLOCK_SIZE_MAX
Maximum allowed block size (2 MB = 2^21).
#define ZXC_BLOCK_SIZE_MIN
Minimum allowed block size (4 KB = 2^12).
#define ZXC_BLOCK_SIZE_DEFAULT
Default block size (512 KB).
#define ZXC_DICT_SIZE_MAX
Maximum dictionary content size in bytes (64 KB - 1).
#define ZXC_HUF_TABLE_SIZE
Size of a packed literal Huffman code-lengths table (256 symbols, 4 bits each): the shared table in a...
@ ZXC_ERROR_SRC_TOO_SMALL
Source buffer too small or truncated input.
@ ZXC_OK
Success (no error).
#define ZXC_FILE_FLAG_HAS_CHECKSUM
Bit flag in the Flags byte indicating checksum presence (bit 7).
#define ZXC_SEQ_OFF_MASK
Mask to extract Offset from a GHI sequence.
static int zxc_ss_prem_rle_q8(const int level)
Per-level RLE-vs-RAW decode premium (Q8) for the space-speed selector.
static uint32_t zxc_seek_group_len(const uint64_t nblocks, const uint64_t g)
Blocks in group g of nblocks: ZXC_SEEK_GROUP, fewer for the last.
#define ZXC_BITMAP_WORDS(n_bits)
Number of uint64_t words needed to hold a bitmap of n_bits.
#define ZXC_SEEK_GROUP
Blocks per group.
#define ZXC_ALIGN_CL(x)
Round x up to the next cache-line boundary.
#define ZXC_GLO_HEADER_BINARY_SIZE
Binary size of a GLO block sub-header.
#define ZXC_ALWAYS_INLINE
Forces a function to be inlined (fallback for non-GCC/Clang/MSVC compilers).
#define ZXC_OPT_LONG_MATCH_SKIP
Threshold above which find_best_match is skipped at intra-match positions, keeping the parser O(N) on...
#define ZXC_HASH_GOLDEN64
Golden-ratio prime: header hashes and the digest spread.
#define ZXC_ALIGNMENT_MASK
Bitmask for cache-line alignment checks.
#define ZXC_LZ_MAX_DIST
Maximum allowed offset distance.
#define ZXC_BLOCK_FORMAT_OVERHEAD
Worst-case format overhead inside a single block beyond the outer 8-byte block header and the optiona...
static uint64_t zxc_seek_table_bytes(const uint64_t nblocks)
Byte size of the groups for nblocks blocks, in 64 bits.
#define ZXC_MAX_VARINT_VALUE
Maximum legitimate value a varint can decode to.
#define ZXC_HUF_MAX_CODE_LEN_ULTRA
Maximum Huffman code length, in bits: the ceiling the decoder's on-wire validation accepts (and the l...
static int zxc_ss_prem_huf_q8(const int level)
Per-level Huffman/PivCo-vs-RAW decode premium (Q8) for the space-speed selector.
#define ZXC_TOKEN_ML_MASK
Mask to extract Match Length from a GLO token.
static uint64_t zxc_seek_group_count(const uint64_t nblocks)
Groups holding nblocks blocks; the last one may be partial.
#define ZXC_FILE_CHECKSUM_ALGO_MASK
Mask for the checksum algorithm id (bits 0-3).
#define ZXC_SEQ_ML_BITS
Bits for Match Length in a GHI sequence.
#define ZXC_LZ_MINDIST
Match distance floor the encoder holds to at levels 1 to 5, sized to the decoder's widest match-copy ...
#define ZXC_SEEK_SIZE_ENTRY
One block's on-disk size, u32.
#define ZXC_LZ_MIN_MATCH_LEN
Minimum match length for an LZ77 match.
#define ZXC_GLO_DESC_MAX_SIZE
Widest GLO section descriptors: the literal and token section sizes.
#define ZXC_LZ_WINDOW_SIZE
Sliding window size (64 KB).
#define ZXC_PAD_SIZE
Safety padding appended to buffers to tolerate overruns.
#define ZXC_FILE_FLAG_HAS_DICTIONARY
Bit flag in the Flags byte indicating a dictionary is required (bit 6).
static uint32_t zxc_seek_size_field(const uint64_t table_bytes)
SEK header size field: table_bytes with its high half folded onto the low one.
#define ZXC_LZ_OFFSET_BIAS
Base bias added to encoded offsets (stored = actual - bias).
#define ZXC_BLOCK_HEADER_SIZE
Block header size: Type(1)+Flags(1)+Reserved(1)+Checksum(1)+CompSize(4).
#define ZXC_HUF_MAX_CODE_LEN_DENSITY
Encoder code-length cap for levels up to ZXC_LEVEL_DENSITY (below ZXC_LEVEL_ULTRA): shallow 8-bit tre...
#define ZXC_FILE_FLAG_HAS_SEEK_TABLE
Bit flag in the Flags byte: a SEK block sits between the EOF block and the footer (bit 5).
#define ZXC_HUF_MARGIN_SHIFT
Huffman margin shift: source of the legacy below-ULTRA premium used by zxc_ss_prem_huf_q8 (the frozen...
#define ZXC_BLOCK_LIT_SLACK
Readable bytes a GLO/GHI payload guarantees after its literal section.
#define ZXC_GLO_MAX_INLINE_ML
Longest match a GLO sequence carries without a varint extension.
#define ZXC_HASH_MULT64
Second multiplier of the 16-byte header hash (zxc_hash16).
#define ZXC_TOKEN_ML_BITS
Bits for Match Length in a GLO token.
#define ZXC_SEQ_OFF_BITS
Bits for Offset in a GHI sequence.
#define ZXC_HASH_XORSHIFT64
Vigna's xorshift* multiplier: the 5-byte LZ hash and the digest fold.
#define ZXC_SEQ_LL_BITS
Bits for Literal Length in a GHI sequence.
static uint32_t zxc_read_varint(const uint8_t **ptr, const uint8_t *end)
Reads a Prefix Varint encoded integer.
#define ZXC_PIVCO_NODE_SLOTS
Node-indexed array size: every node, plus a slot for the lone-symbol root's missing child.
#define ZXC_RLE_MARGIN_SHIFT
RLE margin shift: source of the legacy below-ULTRA premium used by zxc_ss_prem_rle_q8 (256 >> shift r...
#define ZXC_SEEK_ANCHOR_SIZE
Group anchor: offset of its first block, u64.
#define ZXC_LZ_MINDIST_PROBE_PER_KB
Probe sampling: one position per KB, clamped.
#define ZXC_CACHE_LINE_SIZE
Assumed CPU cache line size for alignment.
#define ZXC_LZ_WINDOW_MASK
Mask for ring-buffer indexing into chain_table (power-of-two window).
#define ZXC_LZ_MINDIST_MAX_SHORT_PCT
Short-distance hit rate, in percent, above which a block keeps its short match distances.
static int zxc_magic_prefix_ok(const uint8_t *p, const size_t n)
Whether the first n bytes (up to 4) at p agree with the magic word, so a frame may start there: the c...
#define ZXC_TOKEN_LIT_BITS
Bits for Literal Length in a GLO token.
#define ZXC_HUF_NUM_SYMBOLS
Alphabet size: one entry per possible byte value.
#define ZXC_DECOMPRESS_TAIL_PAD
Tail padding required on the decompression destination buffer.
@ ZXC_LEVEL_ULTRA
Maximum density: Huffman-coded literals and sequence tokens.
@ ZXC_LEVEL_FASTEST
Fastest compression; lowest ratio.
@ ZXC_LEVEL_DENSITY
Higher density: adds Huffman-coded literals on top of COMPACT.
struct zxc_seekable_s zxc_seekable
Opaque handle for a seekable ZXC archive.
Compression / decompression context.
uint32_t offset_mask
(1U << offset_bits) - 1
uint32_t * lit_freq_acc
Trainer hook: when non-NULL, the GLO encoder accumulates post-LZ literal byte frequencies here (256 e...
uint8_t * hash_tags
Split tag table for fast match rejection (8-bit tags).
zxc_dict_huf_state_t * dict_huf
Tree-at-attach state (PivCo tree + codes + code lengths), carved from the workspace only when dict_si...
uint8_t * buf_split
Match-splitting scratch, one byte per sequence.
size_t lit_buffer_cap
Current capacity of the scratch buffer.
void * memory_block
Single allocation block owner.
size_t opt_scratch_cap
Current capacity of opt_scratch in bytes.
size_t work_buf_cap
Capacity of the work buffer.
void * entropy_block
Lazy allocation backing tok_buffer + pivco_scratch (heap decode contexts, first entropy block only).
size_t pivco_scratch_cap
Capacity of pivco_scratch in bytes.
int compression_level
Compression level.
uint32_t epoch
Current epoch for lazy hash table invalidation.
uint32_t * buf_sequences
Buffer for sequence records (packed: LL(8)|ML(8)|Offset(16)).
uint8_t * lit_buffer
Scratch buffer for literals (RLE / Huffman).
uint8_t * work_buf
Padded scratch buffer for buffer-API decompression.
uint32_t * hash_table
Hash table for LZ77 match positions (epoch|pos).
uint32_t offset_bits
log2(chunk_size) - governs epoch_mark shift.
size_t chunk_size
Effective block size in bytes.
size_t tok_buffer_cap
Capacity of tok_buffer in bytes.
uint8_t * buf_tokens
Buffer for token sequences.
uint8_t * buf_extras
Buffer for extra lengths (vbytes for LL/ML).
uint8_t * dict_buffer
[dict | data] concat scratch carved from memory_block when dict_size > 0 (NULL otherwise).
uint8_t * pivco_scratch
Level ping-pong scratch for PivCo decode.
zxc_glo_split_hist_t * buf_split_hist
Match-splitting escape histograms.
size_t dict_size
Dictionary prefill size (0 = no dictionary).
uint8_t * literals
Buffer for literal bytes.
uint8_t * opt_scratch
Optimal-parser DP scratch (level >= 6 only, lazy-allocated, packs dp/parent_len/parent_off/actions).
uint16_t * chain_table
Chain table for collision resolution.
int checksum_enabled
1 if checksum calculation/verification is enabled.
int dict_huf_tree_ok
1 when *dict_huf is built and valid.
uint32_t max_epoch
1U << (32 - offset_bits)
uint8_t * tok_buffer
Decode scratch for a Huffman-coded GLO token section (enc_tok == HUFFMAN); NULL on compress.
uint16_t * buf_offsets
Buffer for offsets.
size_t dict_buffer_cap
Capacity of dict_buffer in bytes (0 = none).
What zxc_scan_container learns about a container.
int uses_dict
A frame bound to a dictionary.
uint64_t frames
ZXC frames.
uint64_t dsize
Sum of the stored decompressed sizes.
uint32_t first_dict_id
Dictionary id of the first frame, 0 without one.
Frame-constant dictionary Huffman state, prebuilt once at attach.
zxc_pivco_tree_t tree
PivCo tree from the shared literal table.
What a frame's header and footer declare, read without decoding.
Workspace of zxc_huf_nudge_code_lengths: tables and DP planes, once a 10 KiB frame and a per-block al...
Trace-back stack frame for the package-merge code-length recovery.
int16_t idx
Item index within that level.
int8_t lvl
Package-merge level being traced back.
Boundary package-merge work item.
int16_t right
Right child index, or -1 for a leaf.
int16_t sym
Symbol index for a leaf, or -1 for an internal node.
int16_t left
Left child index, or -1 for a leaf.
uint32_t weight
Accumulated weight (summed frequency) of the package.
A live symbol and its weight, the package-merge sort key.
Search parameters for LZ77 compression levels.
int lazy_attempts
Maximum number of candidates explored during lazy evaluation (same semantics as search_depth but appl...
int search_depth
Maximum number of candidates explored in the hash chain per position.
int use_lazy
Enable lazy matching.
int lazy_len_threshold
Skip lazy evaluation when the current match length already reaches this threshold: a match this long ...
uint32_t step_shift
Acceleration factor for step size: step = step_base + (distance >> step_shift).
uint8_t split_max
Longest match re-emitted as inline pieces (zxc_glo_split_block), in the token's units (length - ZXC_L...
int sufficient_len
"Good enough" match length: once a match reaches this threshold the chain walk stops immediately,...
uint32_t min_offset
Shortest match distance the parser may emit; 1 = unconstrained.
uint32_t step_base
Base step size when advancing through unmatched literals.
A PivCo code tree: its canonical shape, by depth.
void * ctx
Opaque state for read_at.
uint64_t size
Container size in bytes.
int(* read_at)(const struct zxc_scan_src_s *src, uint64_t off, void *dst, size_t len)
Reads len bytes at off; NULL reads from data.
const uint8_t * data
Container bytes when read_at is NULL.
Where a container scan reads from: memory, or a positioned callback (the FILE* size query).
Single point of override for the C-library dependencies of libzxc.
static uint64_t zxc_le64(const void *p)
Reads a little-endian 64-bit value from a possibly unaligned address.
zxc_block_type_t
Block types, i.e.
int zxc_write_file_header(uint8_t *dst, const size_t dst_capacity, const size_t chunk_size, const int has_checksum, const uint32_t dict_id, const int has_seek)
Writes the standard ZXC file header into dst.
static int zxc_ctz32(const uint32_t x)
Counts trailing zeros, returning 32 for a zero input.
int zxc_write_glo_header_and_desc(uint8_t *dst, const size_t rem, const zxc_gnr_header_t *gh, const uint32_t lit_comp, const uint32_t tok_comp)
Writes a GLO sub-header followed by its section descriptors.
size_t zxc_huf_calc_size(const uint32_t *freq, const uint8_t *code_len, int with_header)
Exact encoded size (bytes) of a PivCo section for this histogram and code lengths; includes the 128-b...
#define ZXC_HUF_NUDGE_DP_M
Slot-ledger DP bound, coarse symbols per plane axis; the nudge groups symbols to stay under it.
int zxc_read_block_header(const uint8_t *src, const size_t src_size, zxc_block_header_t *bh)
Reads and parses a ZXC block header from src.
void zxc_cctx_free(zxc_cctx_t *ctx)
Releases the internal buffers owned by a context.
static uint32_t zxc_le32(const void *p)
Reads a little-endian 32-bit value from a possibly unaligned address.
int zxc_write_block_header(uint8_t *dst, const size_t dst_capacity, const zxc_block_header_t *bh)
Encodes a block header into dst.
#define ZXC_GLO_SPLIT_CTX_BITS
Longest escape history a context keys on; small blocks shorten it (down to 2 bits) towards 16 samples...
static void zxc_copy32(void *dst, const void *src)
Copies 32 bytes from source to destination using SIMD when available.
int zxc_parse_file_footer(const uint8_t *end, size_t avail, uint64_t *src_size, uint64_t *compressed_size, size_t *sizes_len)
Parses the sizes back from the end of a frame.
int zxc_huf_encode_section_dict(const uint8_t *literals, size_t n_literals, const uint32_t *freq, const uint8_t *code_len, const zxc_pivco_tree_t *tree, const uint32_t *codes, uint8_t *dst, size_t dst_cap)
Encode a PivCo section against a prebuilt dict tree/codes (no header).
static int zxc_huf_enc_max_code_len(const int level)
Encoder Huffman code-length cap for a compression level: levels below ZXC_LEVEL_ULTRA use ZXC_HUF_MAX...
static void zxc_frame_info_copy(zxc_frame_info_t *info, const size_t info_size, const zxc_frame_info_t *got)
Copies the fields of got that fit the caller's info_size bytes.
static int zxc_validate_block_size(const size_t bs)
Validates a block size.
static zxc_scan_src_t zxc_scan_src_mem(const uint8_t *data, const size_t size)
A scan source over size bytes of memory at data.
int zxc_scan_frame(const zxc_scan_src_t *src, uint64_t end, uint64_t *start, zxc_frame_info_t *info, size_t *footer_len)
Measures the frame ending at end without decoding: its footer's compressed size gives where it starts...
int zxc_huf_encode_section(const uint8_t *literals, size_t n_literals, const uint32_t *freq, const uint8_t *code_len, uint8_t *dst, size_t dst_cap)
Encode a PivCo literal section (128-byte lengths header + payload).
int zxc_cctx_alloc_entropy_scratch(zxc_cctx_t *ctx)
Lazily allocates the decode-side entropy scratch (tok_buffer + pivco_scratch) for a heap context init...
int zxc_cctx_init_in_workspace(zxc_cctx_t *ctx, void *workspace, const size_t workspace_size, const size_t chunk_size, const int mode, const int level, const int checksum_enabled, const size_t dict_size, const int defer_entropy_scratch)
Initialises a compression / decompression context inside a caller-supplied workspace.
int zxc_seek_table_header(uint8_t *dst, size_t dst_capacity, uint64_t num_blocks)
Writes a seek table's block header for num_blocks entries.
int zxc_container_next(const zxc_scan_src_t *src, uint64_t pos)
Tells whether a frame starts at pos.
int zxc_check_seek_header(const uint8_t *hdr, size_t avail, uint64_t total_out, size_t block_size, uint64_t *sek_bytes)
Checks the SEK block header the file header announced, on the avail bytes present.
int zxc_read_file_header(const uint8_t *src, const size_t src_size, size_t *out_block_size, int *out_has_checksum, uint32_t *out_dict_id, int *out_has_seek)
Validates and reads the ZXC file header from src.
int zxc_huf_decode_section_dict(const uint8_t *payload, size_t payload_size, uint8_t *dst, size_t n, const zxc_pivco_tree_t *tree, uint8_t *scratch)
Decode a PivCo dict section against a prebuilt dict tree.
static void zxc_store_le64(void *p, const uint64_t v)
Writes a 64-bit value little-endian to a possibly unaligned address.
static int zxc_level_clamp(const int level)
Clamps a resolved compression level to the supported ceiling.
static zxc_lz77_params_t zxc_get_lz77_params(const int level)
Retrieves LZ77 compression parameters based on the specified compression level.
void zxc_seekable_attach_owned_ctx(zxc_seekable *s, void *ctx)
Hands ownership of a heap-allocated reader context to a seekable handle.
int zxc_huf_build_code_lengths(const uint32_t *freq, uint8_t *code_len, void *scratch, int max_code_len)
Build length-limited canonical Huffman code lengths from a frequency table.
static uint32_t zxc_log2_u32(const uint32_t v)
Integer log-base-2 for a 32-bit value.
int zxc_scan_whole_frame(const zxc_scan_src_t *src, zxc_frame_info_t *info, size_t *footer_len)
The frame that must span all of src: zxc_get_frame_info() and its FILE* twin.
static uint64_t zxc_digest_combine(const uint64_t acc, const uint32_t block_checksum)
Folds a data block's 32-bit checksum into the running archive digest.
size_t zxc_cctx_compute_workspace_size(const size_t chunk_size, const int mode, const int level, const size_t dict_size)
Returns the byte count that zxc_cctx_init would allocate for the given parameters.
static size_t zxc_block_size_ceil(const size_t v)
Branchless bit_ceil: smallest power of two >= v, clamped to ZXC_BLOCK_SIZE_MIN.
static uint64_t zxc_seek_block_count(const uint64_t total_decomp, const size_t block_size)
Blocks in total_decomp bytes of block_size: the seek table's entry count, which the SEK header's fiel...
static uint16_t zxc_le16(const void *p)
Reads a little-endian 16-bit value from a possibly unaligned address.
size_t zxc_huf_calc_size_dict(const uint32_t *freq, const uint8_t *code_len, const zxc_pivco_tree_t *tree)
zxc_huf_calc_size for a dict section: prebuilt tree, no header.
static uint16_t zxc_hash16(const uint8_t *p)
Computes the 2-byte checksum for file and dictionary headers.
void zxc_huf_nudge_cost(const uint8_t *code_len, const uint32_t *freq, uint64_t *bits, uint64_t *touches)
Modeled (bits, level-touches) decode cost of one code-length vector.
static void zxc_store_le16(void *p, const uint16_t v)
Writes a 16-bit value little-endian to a possibly unaligned address.
static uint8_t zxc_hash8(const uint8_t *p)
Computes the 1-byte checksum for block headers.
int zxc_read_ghi_header(const uint8_t *src, const size_t len, zxc_gnr_header_t *gh)
Reads a GHI sub-header from a buffer.
int zxc_decompress_chunk_wrapper_dict(const zxc_cctx_t *ctx, const uint8_t *src, const size_t src_sz, uint8_t *dst, const size_t dst_cap, const uint64_t block_index)
Public dictionary chunk decoder.
int zxc_compress_chunk_wrapper(zxc_cctx_t *ctx, const uint8_t *src, const size_t src_sz, uint8_t *dst, const size_t dst_cap, const uint64_t block_index)
Compresses one chunk through the runtime ISA dispatch.
int zxc_check_file_footer(const uint8_t *footer, size_t avail, const zxc_footer_layout_t *l, uint64_t src_size, uint64_t *digest)
Checks the footer a sequential reader reaches against l, the one the frame implies,...
static int zxc_footer_dsize_plausible(const uint64_t dsize, const size_t chunk_size, const uint64_t comp_size)
Whether a footer's decompressed size is reachable for this archive.
int zxc_read_frame_info(const uint8_t *header, const uint8_t *tail, size_t tail_len, uint64_t total, zxc_frame_info_t *info, size_t *footer_len)
Validates a frame from its header and the end of its bytes: the one check behind zxc_get_frame_info()...
uint32_t zxc_glo_split_hist_t[4][2][1U<< 8]
zxc_glo_split_analyze's escape histograms: four rotating lanes of [escape][context] counts,...
static void zxc_store_le32(void *p, const uint32_t v)
Writes a 32-bit value little-endian to a possibly unaligned address.
int zxc_write_ghi_header(uint8_t *dst, const size_t rem, const zxc_gnr_header_t *gh)
Writes a GHI sub-header.
int zxc_read_glo_header_and_desc(const uint8_t *src, const size_t len, zxc_gnr_header_t *gh, uint32_t *lit_comp, uint32_t *tok_comp)
Reads a GLO sub-header and its section descriptors from a source buffer.
static size_t zxc_uint_bytes(const uint64_t v)
Fewest little-endian bytes, 1 to 8, that hold v.
int zxc_huf_decode_section(const uint8_t *payload, size_t payload_size, uint8_t *dst, size_t n, uint8_t *scratch)
Decode a PivCo literal section into dst (exactly n bytes).
int zxc_huf_nudge_code_lengths(const uint32_t *freq, uint8_t *code_len, void *scratch, size_t scratch_cap, int max_code_len)
Optionally reshape freshly built code lengths for faster PivCo decode.
int zxc_check_eof_header(const uint8_t *hdr)
Checks an EOF block header against its one valid form: type 255, every other field zero,...
static int zxc_ctz64(const uint64_t x)
Counts trailing zeros, returning 64 for a zero input.
static void zxc_copy16(void *dst, const void *src)
Copies exactly 16 bytes as one vector move where the ISA has one.
static int zxc_block_is_short_dist_bound(const uint8_t *const blk, const size_t size)
Reports whether a block leans on back-references shorter than ZXC_LZ_MINDIST.
static size_t zxc_frame_tail_len(const uint64_t total)
Bytes zxc_read_frame_info() takes from the end of total bytes (at least ZXC_FRAME_MIN_SIZE): all of t...
int zxc_cctx_init(zxc_cctx_t *ctx, const size_t chunk_size, const int mode, const int level, const int checksum_enabled, const size_t dict_size)
Initialises a ZXC compression / decompression context in place.
int zxc_scan_container(const zxc_scan_src_t *src, size_t req_chunk, zxc_container_info_t *info)
Measures a whole container without decoding: frames from the last back to the first through zxc_scan_...
#define ZXC_FOOTER_MAX_SIZE_WITH_DIGEST
Most bytes a footer spans: the digest and the two longest sizes.
size_t zxc_seek_write_group(uint8_t *dst, uint64_t *anchor, const uint32_t *sizes, uint32_t cnt)
Writes one group (*anchor, then cnt sizes) into dst, which holds ZXC_SEEK_GROUP_BYTES,...
int zxc_decompress_chunk_wrapper(const zxc_cctx_t *ctx, const uint8_t *src, const size_t src_sz, uint8_t *dst, const size_t dst_cap, const uint64_t block_index)
Decompresses one chunk through the runtime ISA dispatch.
static void zxc_file_header_sign(uint8_t *h)
Writes the file header checksum (bytes 14-15) over the other 14 bytes.
int zxc_write_file_footer(uint8_t *dst, const size_t dst_capacity, const uint64_t prefix, const uint64_t src_size, const uint64_t digest, const int checksum_enabled)
Writes the footer of a frame whose first prefix bytes precede it.
int64_t zxc_compress_block_at(zxc_cctx *cctx, const void *src, size_t src_size, void *dst, size_t dst_capacity, const zxc_compress_opts_t *opts, uint64_t block_index)
zxc_compress_block, its checksum seeded with block_index (public entry: 0).
static zxc_footer_layout_t zxc_footer_layout(const uint64_t prefix, const uint64_t src_size, const int checksum_enabled)
The footer of a frame whose first prefix bytes precede it.
static uint32_t zxc_checksum(const void *input, const size_t len, const uint64_t seed, const uint8_t hash_method)
Calculates a 32-bit hash for a given input buffer.
int zxc_cctx_attach_dict_huf(zxc_cctx_t *ctx, const uint8_t *lengths)
Attach the shared dictionary literal table to an initialised context.
static int zxc_short_input_verdict(const uint8_t *p, const size_t n)
The verdict on n bytes too short for a frame: the header speaks first, then ZXC_ERROR_SRC_TOO_SMALL.
void zxc_huf_pack_lengths(const uint8_t *code_len, uint8_t *out)
Pack per-symbol code lengths into the 128-byte (4-bit nibble) header.
int zxc_decompress_chunk_wrapper_safe(const zxc_cctx_t *ctx, const uint8_t *src, const size_t src_sz, uint8_t *dst, const size_t dst_cap, const uint64_t block_index)
Exact-capacity variant for the safe block API; dispatch table only.
static void zxc_opt_dp_sizes(const size_t chunk_size, size_t *sz_dp, size_t *sz_pl, size_t *sz_po, size_t *sz_bm)
The four DP partitions the optimal parser carves out of opt_scratch.
int zxc_huf_dict_tree_build(const uint8_t *packed_lengths, zxc_pivco_tree_t *tree, uint32_t *codes, uint8_t *code_len)
Unpack a dict table's packed lengths and prebuild its tree, codes and code lengths,...
int zxc_huf_unpack_lengths(const uint8_t *in, uint8_t *code_len)
Unpack and structurally validate a 128-byte packed lengths header.
zxc_section_encoding_t
Specifies the encoding methods used for internal data sections.