| Title: | Portable Byte Compression with a Pluggable Codec Registry |
|---|---|
| Description: | Compresses and decompresses raw vectors through a single codec-neutral interface backed by a runtime registry, so the set of available codecs is discovered rather than fixed at compile time. The 'DEFLATE' family ('gzip', 'zlib', and headerless 'DEFLATE'), 'Zstandard' and 'LZ4' (frame and block formats) are built in from vendored 'miniz', 'zstd' and 'lz4' sources, requiring no system compression library. Decompression enforces configurable output-size and expansion-ratio limits and reports failures through structured conditions. A registered C-callable interface lets other packages drive the codecs from C and register codecs of their own. The formats are specified in Deutsch (1996) <doi:10.17487/RFC1951>, Deutsch and Gailly (1996) <doi:10.17487/RFC1950>, Deutsch (1996) <doi:10.17487/RFC1952>, and Collet and Kucherawy (2021) <doi:10.17487/RFC8878>. |
| Authors: | Pedro Baltazar [aut, cre, cph], Rich Geldreich [ctb, cph] (author of the bundled miniz library), Tenacious Software LLC [cph] (copyright holder of the bundled miniz library), RAD Game Tools [cph] (copyright holder of the bundled miniz library), Valve Software [cph] (copyright holder of the bundled miniz library), Martin Raiber [ctb, cph] (contributor to and copyright holder of the bundled miniz library), Alex Evans [ctb] (author of the PNG writer in the bundled miniz library), Alistair Moffat [ctb] (co-author of the code-length algorithm in the bundled miniz library), Jyrki Katajainen [ctb] (co-author of the code-length algorithm in the bundled miniz library), Yann Collet [ctb, cph] (author of the bundled LZ4 library and of the bundled Zstandard library's xxHash), Meta Platforms, Inc. and affiliates [cph] (copyright holder of the bundled Zstandard library), Tino Reichardt [ctb, cph] (threading code in the bundled Zstandard library) |
| Maintainer: | Pedro Baltazar <[email protected]> |
| License: | MIT + file LICENSE |
| Version: | 0.1.0.9000 |
| Built: | 2026-11-12 10:09:51 UTC |
| Source: | https://github.com/pedrobtz/zukomp |
Is a codec implementation available?
komp_codec_available(codec)komp_codec_available(codec)
codec |
A codec name, as listed in |
TRUE if an implementation is registered, FALSE if the codec is
known to zukomp but not installed. An unknown name is an error of class
zukomp_unsupported_codec, since it is far more likely to be a typo
than a deliberate probe.
komp_codec_available("identity") komp_codec_available("zstd") # a codec name zukomp reserves, with no implementation released yet komp_codec_available("brotli")komp_codec_available("identity") komp_codec_available("zstd") # a codec name zukomp reserves, with no implementation released yet komp_codec_available("brotli")
Every codec this build of zukomp knows the name of, whether or not an implementation is present, plus any codec registered by another package. This is the R-visible face of the registry: it is how you discover what can be compressed, at what levels, and which HTTP content-coding each codec corresponds to.
komp_codecs()komp_codecs()
Built in are identity, the DEFLATE family (deflate-raw, zlib,
gzip), zstd, and LZ4 as two codecs: lz4-frame, the self-describing
frame format, and lz4-block, one bare block with no header.
A codec that is declared but not installed still gets a row, with
available = FALSE and NA for everything capability-shaped. That is
deliberate: "brotli is a codec zukomp knows, with no implementation here"
is a more useful answer than pretending the codec does not exist.
A data frame with one row per codec and the columns:
Codec name, as accepted by the codec argument elsewhere.
Is an implementation registered?
Supported directions; NA if unavailable.
Codec-native compression
levels. NA when the codec has no level axis, and when it is
unavailable. Levels are not comparable between codecs.
Where the abstract levels "fast" and
"best" land for this codec. These are not level_min and
level_max: for the DEFLATE family level 0 is stored blocks, so
"fast" is 1, and a codec whose level is an acceleration factor
inverts the mapping entirely. Only the codec knows, so it declares
them.
Can komp_detect() recognise this codec from its
bytes? Headerless formats cannot be detected and must be named.
Does the codec support a mid-stream flush – "put the
bytes on the wire now"? NA if unavailable. A caller streaming a
request body should check this before committing to a codec, rather
than discovering it mid-body.
The HTTP content-coding token, or NA.
Package that registered the implementation, or NA.
The built-in codecs implement the formats specified in Deutsch, P. (1996) "DEFLATE Compressed Data Format Specification version 1.3", RFC 1951, doi:10.17487/RFC1951; Deutsch, P. and Gailly, J-L. (1996) "ZLIB Compressed Data Format Specification version 3.3", RFC 1950, doi:10.17487/RFC1950; Deutsch, P. (1996) "GZIP file format specification version 4.3", RFC 1952, doi:10.17487/RFC1952; Collet, Y. and Kucherawy, M. (2021) "Zstandard Compression and the 'application/zstd' Media Type", RFC 8878, doi:10.17487/RFC8878; and the LZ4 frame and block format descriptions, https://github.com/lz4/lz4/tree/dev/doc.
codecs <- komp_codecs() codecs[, c("id", "available", "content_encoding")] # what this build can actually decompress right now codecs$id[which(codecs$can_decode)]codecs <- komp_codecs() codecs[, c("id", "available", "content_encoding")] # what this build can actually decompress right now codecs$id[which(codecs$can_decode)]
Bytes in, bytes out. Character input is not accepted: encoding is a
decision the caller must make explicitly, so convert with
charToRaw() or iconv() first.
komp_compress(x, codec = "gzip", level = NULL)komp_compress(x, codec = "gzip", level = NULL)
x |
A raw vector. |
codec |
Codec name, as listed in |
level |
Compression level. Either a codec-native whole number, one of
the abstract names Numeric levels are not comparable between codecs: |
A raw vector.
komp_decompress(), komp_codecs()
x <- charToRaw(strrep("compress me ", 100)) z <- komp_compress(x) length(x) length(z) identical(komp_decompress(z, "gzip"), x) # gzip output is deterministic: no timestamp, no filename identical(komp_compress(x), komp_compress(x)) # abstract levels port across codecs; numeric ones do not length(komp_compress(x, level = "fast")) length(komp_compress(x, level = "best")) length(komp_compress(x, "zstd", level = "best")) length(komp_compress(x, "lz4-frame"))x <- charToRaw(strrep("compress me ", 100)) z <- komp_compress(x) length(x) length(z) identical(komp_decompress(z, "gzip"), x) # gzip output is deterministic: no timestamp, no filename identical(komp_compress(x), komp_compress(x)) # abstract levels port across codecs; numeric ones do not length(komp_compress(x, level = "fast")) length(komp_compress(x, level = "best")) length(komp_compress(x, "zstd", level = "best")) length(komp_compress(x, "lz4-frame"))
Decompress a raw vector
komp_decompress( x, codec = "auto", max_output = getOption("zukomp.max_output", 1024^3), max_ratio = getOption("zukomp.max_ratio", NULL) )komp_decompress( x, codec = "auto", max_output = getOption("zukomp.max_output", 1024^3), max_ratio = getOption("zukomp.max_ratio", NULL) )
x |
A raw vector holding a complete compressed stream. |
codec |
Codec name, as listed in |
max_output |
Refuse to produce more than this many bytes. Defaults
to 1 GiB, overridable with |
max_ratio |
Refuse to expand by more than this factor. |
A stream may hold several gzip members, or several zstd or LZ4 frames,
back to back; they decode as one, as the reference tools do. Anything
else after the end of the stream is an error of class
zukomp_trailing_bytes.
An lz4-block stream is one bare LZ4 block, which records neither its
decoded size nor where it ends. Decoding one therefore searches for the
size, bounded by max_output, and a block cut short can be a valid,
shorter block: nothing in the format can tell. Prefer lz4-frame
wherever the format is yours to choose.
A raw vector.
komp_compress(), komp_codecs()
z <- komp_compress(charToRaw(strrep("data ", 200)), "gzip") rawToChar(komp_decompress(z, "gzip")) # a small input that would expand a long way is stopped, not allocated bomb <- komp_compress(raw(1e6), "gzip") length(bomb) try(komp_decompress(bomb, "gzip", max_output = 1024)) # zstd and lz4-frame streams are detected by their magic bytes komp_decompress(komp_compress(charToRaw("hello"), "zstd"))z <- komp_compress(charToRaw(strrep("data ", 200)), "gzip") rawToChar(komp_decompress(z, "gzip")) # a small input that would expand a long way is stopped, not allocated bomb <- komp_compress(raw(1e6), "gzip") length(bomb) try(komp_decompress(bomb, "gzip", max_output = 1024)) # zstd and lz4-frame streams are detected by their magic bytes komp_decompress(komp_compress(charToRaw("hello"), "zstd"))
Detection is a property of the codec registry, not a hardcoded list: a codec registered by another package becomes detectable as soon as it advertises magic bytes.
komp_detect(x)komp_detect(x)
x |
A raw vector; only the leading bytes are examined. |
gzip, zstd and lz4-frame are recognised by their magic bytes
(1f 8b, 28 b5 2f fd and 04 22 4d 18).
Not every format can be detected. Raw DEFLATE, raw LZ4 blocks
(lz4-block), raw Snappy and brotli have no header to recognise, so
they return NA and must be named explicitly. This is deliberate: guessing wrong for a
headerless format means silently returning the wrong bytes.
zlib is recognised by a header predicate rather than a constant, so
it carries a small false-positive rate – roughly one arbitrary byte pair
in a thousand looks like a valid zlib header. Codecs with real magic are
always tested first.
The codec's name, or NA_character_ if nothing matched.
komp_codecs(), whose detectable column says which codecs can
be found this way.
komp_detect(komp_compress(charToRaw("hello"), "gzip")) komp_detect(komp_compress(charToRaw("hello"), "zlib")) komp_detect(komp_compress(charToRaw("hello"), "zstd")) # headerless formats are not guessed at komp_detect(komp_compress(charToRaw("hello"), "deflate-raw"))komp_detect(komp_compress(charToRaw("hello"), "gzip")) komp_detect(komp_compress(charToRaw("hello"), "zlib")) komp_detect(komp_compress(charToRaw("hello"), "zstd")) # headerless formats are not guessed at komp_detect(komp_compress(charToRaw("hello"), "deflate-raw"))
What this build of zukomp actually contains: its version, the ABI version other packages link against, the codecs it registered, and the vendored sources compiled into it with the trim applied to them.
komp_info()komp_info()
Reported from the compiled library rather than read from
tools/vendor/manifest.tsv, because the manifest is not installed and
what matters here is what was actually built.
A list with version, abi_version, codecs, vendored and
build_flags. version is a character string rather than a
package_version object: this is diagnostic output that mostly ends up
pasted into a log line or a bug report, and paste() on a
package_version needs an as.character() at every call site. Compare
against utils::packageVersion() with
package_version(komp_info()$version) if you need ordering.
info <- komp_info() info$version info$vendored info$build_flagsinfo <- komp_info() info$version info$vendored info$build_flags