file1.txt ok
file2.txt ok
func ZipDecompressor(opts ...DOption) func(r io.Reader) io.ReadCloser
ZipDecompressor returns a decompressor that can be registered with zip libraries.
See ZipCompressor for example.
Options can be specified. WithDecoderConcurrency(1) is forced,
and by default a 128MB maximum decompression window is specified.
The window size can be overridden if required.
Offsets [3]int
CompatV155 bool
Level EncoderLevel
DebugOut io.Writer
func WithDecodeAllCapLimit(b bool) DOption
WithDecodeAllCapLimit will limit DecodeAll to decoding cap(dst)-len(dst) bytes,
or any size set in WithDecoderMaxMemory.
This can be used to limit decoding to a specific maximum output size.
Disabled by default.
func WithDecodeBuffersBelow(size int) DOption
WithDecodeBuffersBelow will fully decode readers that have a
`Bytes() []byte` and `Len() int` interface similar to bytes.Buffer.
This typically uses less allocations but will have the full decompressed object in memory.
Note that DecodeAllCapLimit will disable this, as well as giving a size of 0 or less.
Default is 128KiB.
func WithDecoderConcurrency(n int) DOption
WithDecoderConcurrency sets the number of created decoders.
When decoding block with DecodeAll, this will limit the number
of possible concurrently running decodes.
When decoding streams, this will limit the number of
inflight blocks.
When decoding streams and setting maximum to 1,
no async decoding will be done.
When a value of 0 is provided GOMAXPROCS will be used.
By default this will be set to 4 or GOMAXPROCS, whatever is lower.
func WithDecoderDictRaw(id uint32, content []byte) DOption
WithDecoderDictRaw registers a dictionary that may be used by the decoder.
The slice content can be arbitrary data.
func WithDecoderDicts(dicts ...[]byte) DOption
WithDecoderDicts allows to register one or more dictionaries for the decoder.
Each slice in dict must be in the dictionary format produced by
"zstd --train" from the Zstandard reference implementation.
If several dictionaries with the same ID are provided, the last one will be used.
func WithDecoderLowmem(b bool) DOption
WithDecoderLowmem will set whether to use a lower amount of memory,
but possibly have to allocate more while running.
func WithDecoderMaxMemory(n uint64) DOption
WithDecoderMaxMemory allows to set a maximum decoded size for in-memory
non-streaming operations or maximum window size for streaming operations.
This can be used to control memory usage of potentially hostile content.
Maximum is 1 << 63 bytes. Default is 64GiB.
func WithDecoderMaxWindow(size uint64) DOption
WithDecoderMaxWindow allows to set a maximum window size for decodes.
This allows rejecting packets that will cause big memory usage.
The Decoder will likely allocate more memory based on the WithDecoderLowmem setting.
If WithDecoderMaxMemory is set to a lower value, that will be used.
Default is 512MB, Maximum is ~3.75 TB as per zstandard spec.
Decoder provides decoding of zstandard streams.
The decoder has been designed to operate without allocations after a warmup.
This means that you should store the decoder for best performance.
To re-use a stream decoder, use the Reset(r io.Reader) error to switch to another stream.
A decoder can safely be re-used even if the previous stream failed.
To release the resources, you must call the Close() function on a decoder.
func NewReader(r io.Reader, opts ...DOption) (*Decoder, error)
NewReader creates a new decoder.
A nil Reader can be provided in which case Reset can be used to start a decode.
A Decoder can be used in two modes:
1) As a stream, or
2) For stateless decoding using DecodeAll.
Only a single stream can be decoded concurrently, but the same decoder
can run multiple concurrent stateless decodes. It is even possible to
use stateless decodes while a stream is being decoded.
The Reset function can be used to initiate a new stream, which is will considerably
reduce the allocations normally caused by NewReader.
func (d *Decoder) DecodeAll(input, dst []byte) ([]byte, error)
DecodeAll allows stateless decoding of a blob of bytes.
Output will be appended to dst, so if the destination size is known
you can pre-allocate the destination slice to avoid allocations.
DecodeAll can be used concurrently.
The Decoder concurrency limits will be respected.
func (d *Decoder) IOReadCloser() io.ReadCloser
IOReadCloser returns the decoder as an io.ReadCloser for convenience.
Any changes to the decoder will be reflected, so the returned ReadCloser
can be reused along with the decoder.
io.WriterTo is also supported by the returned ReadCloser.
func (d *Decoder) Read(p []byte) (int, error)
Read bytes from the decompressed stream into p.
Returns the number of bytes written and any error that occurred.
When the stream is done, io.EOF will be returned.
func (d *Decoder) Reset(r io.Reader) error
Reset will reset the decoder the supplied stream after the current has finished processing.
Note that this functionality cannot be used after Close has been called.
Reset can be called with a nil reader to release references to the previous reader.
After being called with a nil reader, no other operations than Reset or DecodeAll or Close
should be used.
func (d *Decoder) WriteTo(w io.Writer) (int64, error)
WriteTo writes data to w until there's no more data to write or when an error occurs.
The return value n is the number of bytes written.
Any error encountered during the write is also returned.
func WithAllLitEntropyCompression(b bool) EOption
WithAllLitEntropyCompression will apply entropy compression if no matches are found.
Disabling this will skip incompressible data faster, but in cases with no matches but
skewed character distribution compression is lost.
Default value depends on the compression level selected.
func WithEncoderConcurrency(n int) EOption
WithEncoderConcurrency will set the concurrency,
meaning the maximum number of encoders to run concurrently.
The value supplied must be at least 1.
For streams, setting a value of 1 will disable async compression.
By default this will be set to GOMAXPROCS.
func WithEncoderDict(dict []byte) EOption
WithEncoderDict allows to register a dictionary that will be used for the encode.
The slice dict must be in the dictionary format produced by
"zstd --train" from the Zstandard reference implementation.
The encoder *may* choose to use no dictionary instead for certain payloads.
func WithEncoderDictRaw(id uint32, content []byte) EOption
WithEncoderDictRaw registers a dictionary that may be used by the encoder.
The slice content may contain arbitrary data. It will be used as an initial
history.
package main
import (
"bytes"
"fmt"
"github.com/klauspost/compress/zstd"
func main() {
// "Raw" dictionaries can be used for compressed delta encoding.
source := []byte(`
This is the source file. Compression of the target file with
the source file as the dictionary will produce a compressed
delta encoding of the target file.`)
target := []byte(`
This is the target file. Decompression of the delta encoding with
the source file as the dictionary will produce this file.`)
// The dictionary id is arbitrary. We use zero for compatibility
// with zstd --patch-from, but applications can use any id
// not in the range [32768, 1<<31).
const id = 0
bestLevel := zstd.WithEncoderLevel(zstd.SpeedBestCompression)
w, _ := zstd.NewWriter(nil, bestLevel,
zstd.WithEncoderDictRaw(id, source))
delta := w.EncodeAll(target, nil)
r, _ := zstd.NewReader(nil, zstd.WithDecoderDictRaw(id, source))
out, err := r.DecodeAll(delta, nil)
if err != nil || !bytes.Equal(out, target) {
panic("decoding error")
// Ordinary compression, for reference.
w, _ = zstd.NewWriter(nil, bestLevel)
compressed := w.EncodeAll(target, nil)
// Check that the delta is at most half as big as the compressed file.
fmt.Println(len(delta) < len(compressed)/2)
Output:
func WithEncoderPadding(n int) EOption
WithEncoderPadding will add padding to all output so the size will be a multiple of n.
This can be used to obfuscate the exact output size or make blocks of a certain size.
The contents will be a skippable frame, so it will be invisible by the decoder.
n must be > 0 and <= 1GB, 1<<30 bytes.
The padded area will be filled with data from crypto/rand.Reader.
If `EncodeAll` is used with data already in the destination, the total size will be multiple of this.
func WithLowerEncoderMem(b bool) EOption
WithLowerEncoderMem will trade in some memory cases trade less memory usage for
slower encoding speed.
This will not change the window size which is the primary function for reducing
memory usage. See WithWindowSize.
func WithNoEntropyCompression(b bool) EOption
WithNoEntropyCompression will always skip entropy compression of literals.
This can be useful if content has matches, but unlikely to benefit from entropy
compression. Usually the slight speed improvement is not worth enabling this.
func WithSingleSegment(b bool) EOption
WithSingleSegment will set the "single segment" flag when EncodeAll is used.
If this flag is set, data must be regenerated within a single continuous memory segment.
In this case, Window_Descriptor byte is skipped, but Frame_Content_Size is necessarily present.
As a consequence, the decoder must allocate a memory segment of size equal or larger than size of your content.
In order to preserve the decoder from unreasonable memory requirements,
a decoder is allowed to reject a compressed frame which requests a memory size beyond decoder's authorized range.
For broader compatibility, decoders are recommended to support memory sizes of at least 8 MB.
This is only a recommendation, each decoder is free to support higher or lower limits, depending on local limitations.
If this is not specified, block encodes will automatically choose this based on the input size and the window size.
This setting has no effect on streamed encodes.
func WithWindowSize(n int) EOption
WithWindowSize will set the maximum allowed back-reference distance.
The value must be a power of two between MinWindowSize and MaxWindowSize.
A larger value will enable better compression but allocate more memory and,
for above-default values, take considerably longer.
The default value is determined by the compression level.
func WithZeroFrames(b bool) EOption
WithZeroFrames will encode 0 length input as full frames.
This can be needed for compatibility with zstandard usage,
but is not needed for this package.
Encoder provides encoding to Zstandard.
An Encoder can be used for either compressing a stream via the
io.WriteCloser interface supported by the Encoder or as multiple independent
tasks via the EncodeAll function.
Smaller encodes are encouraged to use the EncodeAll function.
Use NewWriter to create a new instance.
func NewWriter(w io.Writer, opts ...EOption) (*Encoder, error)
NewWriter will create a new Zstandard encoder.
If the encoder will be used for encoding blocks a nil writer can be used.
Close will flush the final output and close the stream.
The function will block until everything has been written.
The Encoder can still be re-used after calling this.
func (e *Encoder) EncodeAll(src, dst []byte) []byte
EncodeAll will encode all input in src and append it to dst.
This function can be called concurrently, but each call will only run on a single goroutine.
If empty input is given, nothing is returned, unless WithZeroFrames is specified.
Encoded blocks can be concatenated and the result will be the combined input stream.
Data compressed with EncodeAll can be decoded with the Decoder,
using either a stream or DecodeAll.
Flush will send the currently written data to output
and block until everything has been written.
This should only be used on rare occasions where pushing the currently queued data is critical.
func (e *Encoder) MaxEncodedSize(size int) int
MaxEncodedSize returns the expected maximum
size of an encoded block or stream.
func (e *Encoder) ReadFrom(r io.Reader) (n int64, err error)
ReadFrom reads data from r until EOF or error.
The return value n is the number of bytes read.
Any error except io.EOF encountered during the read is also returned.
The Copy function uses ReaderFrom if available.
func (e *Encoder) Reset(w io.Writer)
Reset will re-initialize the writer and new writes will encode to the supplied writer
as a new, independent stream.
func (e *Encoder) ResetContentSize(w io.Writer, size int64)
ResetContentSize will reset and set a content size for the next stream.
If the bytes written does not match the size given an error will be returned
when calling Close().
This is removed when Reset is called.
Sizes <= 0 results in no content size set.
Write data to the encoder.
Input data will be buffered and as the buffer fills up
content will be compressed and written to the output.
When done writing, use Close to flush the remaining output
and write CRC if requested.
EncoderLevel predefines encoder compression levels.
Only use the constants made available, since the actual mapping
of these values are very likely to change and your compression could change
unpredictably when upgrading the library.
const (
SpeedFastest EncoderLevel
SpeedDefault
SpeedBetterCompression
SpeedBestCompression
func EncoderLevelFromString(s string) (bool, EncoderLevel)
EncoderLevelFromString will convert a string representation of an encoding level back
to a compression level. The compare is not case sensitive.
If the string wasn't recognized, (false, SpeedDefault) will be returned.
func EncoderLevelFromZstd(level int) EncoderLevel
EncoderLevelFromZstd will return an encoder level that closest matches the compression
ratio of a specific zstd compression level.
Many input values will provide the same compression level.
type Header struct {
SingleSegment bool
WindowSize uint64
DictionaryID uint32
HasFCS bool
FrameContentSize uint64
Skippable bool
SkippableID int
SkippableSize uint32