Squinch C API
Include compress.h to compress and decompress.h to decompress. The headers expose the enum SquinchResult result type and all public functions. The stream format is specified in Format.md, and its implementation is described in Algorithm.md.
Result handling
Every fallible operation returns enum SquinchResult. Success_SquinchResult means the call completed successfully. Parameter errors identify the invalid pointer or setting. InvalidInput_SquinchResult reports malformed, reserved, or incomplete compressed data. OutOfMemory_SquinchResult reports a failed allocation or unrepresentable allocation size.
WindowTooSmall_SquinchResult means that a stream declares a window larger than the maximum requested when creating a decoder. InputAfterEndOfData_SquinchResult rejects nonempty input after a zero-input finish call. NoMoreOutputAvailable_SquinchResult means that a finished stream was fully drained. HeaderNotFullyParsed_SquinchResult means that a decoder metadata accessor was called before it had received all 16 header bytes.
One-shot compression
SquinchCompress compresses one complete input buffer into one output buffer.
enum SquinchResult SquinchCompress(
const void * input,
size_t inputSize,
void * output,
size_t outputSize,
size_t * outBytesWritten,
size_t windowSize,
size_t matchLimit,
size_t bucketCount
);
input may be NULL only when inputSize is zero. output may be NULL only when outputSize is zero. The input and output buffers must not overlap. outBytesWritten must not be NULL and receives bytes written even if the output is too small. SQUINCH_MAXIMUM_COMPRESSED_SIZE(inputSize) provides sufficient capacity when inputSize is at most (SIZE_MAX - 16) / 2.
windowSize is 16 through 65536. matchLimit is zero for SQUINCH_DEFAULT_MATCH_LIMIT or 1 through SQUINCH_MAXIMUM_MATCH_LIMIT. bucketCount is zero for SQUINCH_DEFAULT_BUCKET_COUNT or at least SQUINCH_MINIMUM_BUCKET_COUNT; there is no maximum. inputSize is stored in the header when it is at most 2^40 - 1. Larger values are stored as an unknown size.
Streaming compression
Create a compressor with SquinchCompressorCreate, then supply input and collect output with SquinchCompressorStep.
enum SquinchResult SquinchCompressorCreate(
struct SquinchCompressor ** outCompressor,
uint_least64_t uncompressedSize,
size_t windowSize,
size_t lookAheadSize,
size_t bucketCount,
size_t matchLimit
);
enum SquinchResult SquinchCompressorStep(
struct SquinchCompressor * compressor,
const void * input,
size_t inputSize,
size_t * outInputBytesConsumed,
void * output,
size_t outputSize,
size_t * outOutputBytesWritten
);
lookAheadSize is the number of bytes retained in the look-ahead ring. Zero selects min(windowSize, 1024); a nonzero value must be at least 1. The compressor fills this ring from the supplied input and encodes from it. It refills before deciding an operation when fewer than three bytes are available or when a copy or RLE operation may continue beyond the currently available bytes. Every copied byte is added to the history window immediately and can be read later by the same copy operation. RLE output is not added to the history window. matchLimit and bucketCount use the same zero-default rules as SquinchCompress.
Each successful call may consume part or all of the supplied input and may fill part or all of the supplied output buffer. Consumed input may remain buffered in the look-ahead ring. Resubmit unconsumed input. A call with zero inputSize signals the end of data and causes all remaining look-ahead bytes to be encoded. Continue calling SquinchCompressorStep with zero input until it writes zero bytes. The compressor cannot accept input after finishing. Both count-output pointers must not be NULL. Destroy the compressor with SquinchCompressorDestroy; passing NULL is allowed.
One-shot decompression
SquinchDecompress decodes one complete compressed buffer into one output buffer.
enum SquinchResult SquinchDecompress(
const void * input,
size_t inputSize,
void * output,
size_t outputSize,
size_t * outBytesWritten
);
The input must contain a complete valid stream, including its 16-byte header. The input and output buffers must not overlap. outBytesWritten must not be NULL and receives output produced before a full output buffer or malformed input is detected.
Streaming decompression
Create a decoder with SquinchDecompressorCreate, then use SquinchDecompressorStep for every input and output buffer pair.
enum SquinchResult SquinchDecompressorCreate(
struct SquinchDecompressor ** outDecompressor,
size_t maxWindowSize
);
enum SquinchResult SquinchDecompressorStep(
struct SquinchDecompressor * decompressor,
const void * input,
size_t inputSize,
void * output,
size_t outputSize,
size_t * outInputBytesConsumed,
size_t * outOutputBytesWritten
);
Set maxWindowSize to zero to defer allocation until the full header is available, or set it to 16 through 65536 to reserve storage up front and reject larger stream windows. A step call may write pending output without consuming input. A zero-input call finishes and validates the stream. Continue zero-input calls until no bytes are written. Both count-output pointers must not be NULL. Destroy the decoder with SquinchDecompressorDestroy; passing NULL is allowed.
Header metadata
After the streaming decoder has received all 16 header bytes, these accessors report its metadata:
enum SquinchResult SquinchDecompressorGetUncompressedSize(
const struct SquinchDecompressor * decompressor,
uint64_t * outUncompressedSize
);
enum SquinchResult SquinchDecompressorGetWindowSize(
const struct SquinchDecompressor * decompressor,
size_t * outWindowSize
);
enum SquinchResult SquinchDecompressorGetVersion(
const struct SquinchDecompressor * decompressor,
unsigned char * outVersion
);
Each accessor requires a non-NULL decoder and output pointer. Before header completion, each returns HeaderNotFullyParsed_SquinchResult. An uncompressed size of zero means unknown.