lib/deflate/src/model.zig
daab053ee43316e1809a84551d573ddd1e5bf3d2
1 /// The three wrappings that `decompress` accepts around DEFLATE data, for a caller to pass one tag
2 /// to `decompress` to say which wrapper surrounds the compressed data. The caller picks the tag
3 /// from the file format it reads, for example `zlib` for a PDF content stream.
4 pub const Format = enum {
5 /// A raw stream, with no header and no trailer. The stream carries no checksum, so only the
6 /// structure of the stream itself is checked. The input is DEFLATE data alone, a run of
7 /// compressed blocks in the form RFC 1951 defines.
8 raw,
9 /// The zlib container of RFC 1950. The layout is a two-byte header that names the compression
10 /// method and window size, then the DEFLATE stream, then a four-byte big-endian Adler-32 of the
11 /// expanded data. The header must name method 8 with a window of at most 32 KiB and pass its
12 /// own check value, or the call fails with `error.BadHeader`. A header that asks for a preset
13 /// dictionary fails with `error.PresetDictionaryUnsupported`.
14 zlib,
15 /// The gzip container of RFC 1952. The layout is a header of at least ten bytes, then the
16 /// DEFLATE stream, then a little-endian CRC-32 of the expanded data and the expanded length
17 /// modulo 2^32. The optional extra field, file name and comment in the header are skipped, and
18 /// the optional header checksum is checked. One call reads one gzip member, so a second member
19 /// joined after the first counts as leftover input.
20 gzip,
21 };
22
23 /// Two checks that `decompress` runs after the decoder for the format finishes one compressed
24 /// stream with whatever header and trailer its format adds, a frame, for a caller to choose how
25 /// closely the frame must match the two buffers. The defaults require the input to end with the
26 /// frame and leave the output length free. The PDF reader passes the defaults, and the README
27 /// example turns both checks on.
28 pub const Options = struct {
29 /// Turns on exact input: when true, bytes left in `input` after the frame fail the call with
30 /// `error.TrailingInput`. The option defaults to true. A caller that reads one frame from the
31 /// front of a longer buffer sets it to false and learns the frame's length from
32 /// `Result.consumed`.
33 exact_input: bool = true,
34 /// Turns on exact output: when true, expanded data shorter than `output` fails the call with
35 /// `error.BadSize`. The option defaults to false. A caller that knows the expanded size from
36 /// elsewhere sets it and passes an output buffer of exactly that size.
37 exact_output: bool = false,
38 };
39
40 /// The two byte counts of one successful `decompress` call, for a caller to read after a success
41 /// and learn how much of each buffer the frame used.
42 pub const Result = struct {
43 /// The number of input bytes the frame used, from its first header byte through its last
44 /// trailer byte. For a raw stream the field counts the byte that holds the last bits of the
45 /// stream. The count equals `input.len` after any success with exact input on, the option that
46 /// fails a call when input bytes remain unused.
47 consumed: usize,
48 /// The number of expanded bytes at the front of `output`. The count equals `output.len` after
49 /// any success with exact output on, the option that requires the expanded data to fill the
50 /// output buffer.
51 written: usize,
52 };
53
54 /// Every way `decompress` can fail, for a caller to switch on and tell a buffer that is too small
55 /// from input that is bad. The PDF reader separates `OutputTooSmall`, which means the output buffer
56 /// ran out, from every other tag, which it treats as undecodable input.
57 pub const Error = error{
58 /// The expanded data does not match the Adler-32 in a zlib trailer or the CRC-32 in a gzip
59 /// trailer. The call also returns this error when a gzip header checksum does not match the
60 /// header bytes.
61 BadChecksum,
62 /// A zlib header names a method other than 8, names a window above 32 KiB, or fails its check
63 /// value. The call also returns this error when a gzip header lacks the bytes 1f 8b, names a
64 /// method other than 8, or sets a reserved flag bit.
65 BadHeader,
66 /// The length in a gzip trailer differs from the expanded length modulo 2^32. The call also
67 /// returns this error under exact output when the expanded data is shorter than `output`.
68 BadSize,
69 /// A block header names block type 3, which DEFLATE reserves.
70 InvalidBlockType,
71 /// The compressed data holds a pattern of bits that matches no code in the current table, or a
72 /// length or distance symbol that the format leaves unused.
73 InvalidCode,
74 /// A back-reference reaches further back than the bytes written so far.
75 InvalidDistance,
76 /// The header of a block that carries its own code tables is malformed. The cases are too many
77 /// literal and length codes, a repeat instruction with nothing before it or one that runs past
78 /// the end, or code lengths that form no valid Huffman code.
79 InvalidDynamicHeader,
80 /// The package raises this error when a list of code lengths forms no valid Huffman code.
81 /// `decompress` reports every such failure as `InvalidDynamicHeader`, so a caller of
82 /// `decompress` never receives this tag.
83 InvalidHuffmanTree,
84 /// A block that carries its own code tables gives the end-of-block symbol no code, so the block
85 /// could never end.
86 MissingEndOfBlock,
87 /// The expanded data needs more bytes than `output` has left. The PDF reader turns this tag,
88 /// the one tag about the caller's buffer, into its own capacity error.
89 OutputTooSmall,
90 /// A zlib header sets the flag that asks for a preset dictionary, which the package does not
91 /// support.
92 PresetDictionaryUnsupported,
93 /// Exact input is on and bytes remain in `input` after the frame. A second gzip member joined
94 /// after the first ends here.
95 TrailingInput,
96 /// The input ends before the frame does: inside a header, inside the compressed data, or before
97 /// the trailer. A zlib input under 6 bytes or a gzip input under 18 bytes fails here before any
98 /// decoding.
99 TruncatedInput,
100 /// The length of an uncompressed block does not match the complement stored after it.
101 WrongStoredLength,
102 };