MaxCompression provides a simple C API with two primary functions for one-shot compression and decompression. The library handles all format details internally.
Guarantees:
- All functions are reentrant and thread-safe (no global state)
- All error conditions return error codes (never crash on invalid input)
- Decompressor validates frame headers, CRC32, and block integrity
- Malformed/corrupted input is handled gracefully (returns
MCX_ERR_CORRUPT) - Memory allocation failures are reported (returns
MCX_ERR_ALLOC_FAILED) - Verified with Valgrind memcheck (zero leaks, zero errors) in CI
#include <maxcomp/maxcomp.h>size_t mcx_compress(void* dst, size_t dst_cap,
const void* src, size_t src_size,
int level);Compress src_size bytes from src into dst.
Parameters:
| Parameter | Description |
|---|---|
dst |
Output buffer for compressed data |
dst_cap |
Capacity of output buffer in bytes |
src |
Input data to compress |
src_size |
Size of input data in bytes |
level |
Compression level (1–20, see below) |
Returns: Compressed size in bytes, or an error code (check with mcx_is_error).
Buffer sizing: The output buffer should be at least src_size + 4096 bytes to handle incompressible data safely.
size_t mcx_decompress(void* dst, size_t dst_cap,
const void* src, size_t src_size);Decompress src_size bytes from src into dst.
Parameters:
| Parameter | Description |
|---|---|
dst |
Output buffer for decompressed data |
dst_cap |
Capacity of output buffer in bytes |
src |
Compressed data (MCX format) |
src_size |
Size of compressed data in bytes |
Returns: Decompressed size in bytes, or an error code.
Note: The original size is stored in the MCX frame header. Use dst_cap >= original_size.
int mcx_is_error(size_t result);Check if a return value from mcx_compress or mcx_decompress indicates an error.
Returns: Non-zero if result is an error code, zero if it's a valid size.
const char* mcx_get_error_name(size_t result);Get a human-readable error description.
Returns: Static string describing the error, or "No error" if the result is valid.
typedef struct {
unsigned long long original_size;
unsigned version;
unsigned level;
unsigned strategy;
unsigned flags;
} mcx_frame_info;
size_t mcx_get_frame_info(mcx_frame_info* info,
const void* src, size_t src_size);Read frame metadata from compressed data without decompressing.
Parameters:
| Parameter | Description |
|---|---|
info |
Output structure for frame information |
src |
Compressed data (only header is read) |
src_size |
Size of compressed data |
Returns: 0 on success, or an error code (check with mcx_is_error).
Example:
mcx_frame_info info;
if (!mcx_is_error(mcx_get_frame_info(&info, compressed, comp_size))) {
printf("Original: %llu bytes, Level: %u\n",
info.original_size, info.level);
}| Level | Strategy | Description |
|---|---|---|
| 1–3 | LZ77 greedy + rANS | Fast compression, lowest ratio |
| 4–6 | LZ-HC + rANS | Hash chain match finder, better ratio |
| 7–8 | LZ-HC + AAC | Adaptive arithmetic coding, good ratio |
| 9 | LZ-HC (d=64) + AAC | Deep chains + AAC, best LZ ratio |
| 10–14 | BWT + rANS | Burrows-Wheeler transform, high ratio |
| 20 | Smart Mode | Auto-detect data type, best ratio |
| 24 | LZRC-HC | Fast LZRC with hash chains |
| 26 | LZRC-BT | Best LZRC with binary tree + 64MB window |
| 28 | Context Mixing | 58 context models, 8 neural mixers — PAQ8-class ratio |
Recommendation: Use level 20 for maximum compression ratio with practical speed, level 28 for absolute maximum ratio (archival, ~10 KB/s), level 6 for general purpose, level 3 for speed.
| Code | Name | Description |
|---|---|---|
MCX_ERR_INVALID_PARAM |
Invalid parameter | NULL pointer or zero size |
MCX_ERR_ALLOC_FAILED |
Allocation failed | Out of memory |
MCX_ERR_DST_TOO_SMALL |
Buffer too small | Output buffer insufficient |
MCX_ERR_CORRUPT |
Corrupt data | Invalid or corrupted input |
MCX_ERR_CHECKSUM |
Checksum mismatch | CRC32 verification failed |
mcx_compressandmcx_decompressare reentrant — no global state.- Multiple threads can compress/decompress simultaneously with independent buffers.
- OpenMP parallelism is used internally for block-level compression at higher levels.
#include <maxcomp/maxcomp.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void) {
// Read input
FILE* f = fopen("input.bin", "rb");
fseek(f, 0, SEEK_END);
size_t size = ftell(f);
fseek(f, 0, SEEK_SET);
void* data = malloc(size);
fread(data, 1, size, f);
fclose(f);
// Compress
size_t comp_cap = size + 4096;
void* comp = malloc(comp_cap);
size_t comp_size = mcx_compress(comp, comp_cap, data, size, 20);
if (mcx_is_error(comp_size)) {
fprintf(stderr, "Compression failed: %s\n",
mcx_get_error_name(comp_size));
return 1;
}
printf("Compressed: %zu → %zu (%.2f×)\n",
size, comp_size, (double)size / comp_size);
// Decompress and verify
void* dec = malloc(size);
size_t dec_size = mcx_decompress(dec, size, comp, comp_size);
if (dec_size == size && memcmp(data, dec, size) == 0) {
printf("Roundtrip OK\n");
}
free(data);
free(comp);
free(dec);
return 0;
}Compile:
gcc -O2 -o example example.c -lmaxcomp -lm -lpthread