deflate
Accept input and deliver part or all of a valid compressed stream.
Full chapter and shared rules ↗39ab1ace4bbe0b0e · Source at the matching commit ↗Read the function’s preconditions and results first. Expand the shared rules below for buffer and ownership requirements used throughout this API group.
int ZEXPORT deflate(z_streamp strm, int flush);
Accept input and deliver part or all of a valid compressed stream.
Domain Restricted domain. Effect: consume input, emit output and update progress.
Pre live stream with valid buffers and any active header. next_out is non-NULL and
avail_out > 0; next_in may be NULL only with zero input. flush is Z_NO_FLUSH,
Z_PARTIAL_FLUSH, Z_SYNC_FLUSH, Z_FULL_FLUSH, Z_FINISH or Z_BLOCK.
If output fills during a flush, continue with the same flush and more room.
After finishing begins, supply no new input and continue only with Z_FINISH.
For ordinary format validity, begin from init/deflateReset (or a copy of that history),
use legal dictionary/header setup, standard tuning and no arbitrary priming.
Post accept used <= old avail_in bytes and deliver made <= old avail_out bytes.
Pointers advance by those amounts, available counts fall by them, and totals increase by
them with unsigned wrapping. Input stays unchanged; output outside the delivered prefix
stays unchanged. Some input can remain when output fills. No allocation or free occurs.
Across calls, delivered bytes form a prefix of a valid encoding of accepted input, using
the chosen wrapper, settings and preset dictionary. Completed output decodes to that input.
This specifies valid output, not one unique compressed byte sequence. adler tracks accepted
input using Adler-32 for zlib and CRC-32 for gzip after header emission; raw has no input checksum.
Z_OK means continuation may be needed. Z_STREAM_END occurs only with Z_FINISH, after
all supplied input and all compressed output, including trailer, have been delivered.
The live state remains owned until deflateEnd or reusable via deflateReset.
When a requested flush is fully delivered, Z_BLOCK completes a block without byte padding;
Z_PARTIAL_FLUSH adds an empty fixed block; Z_SYNC_FLUSH makes all preceding input available
to a decoder and ends with an aligned empty stored block. Z_FULL_FLUSH also resets match
history: later blocks do not refer before that completed flush. Restarting a raw decoder there
requires retaining the exact boundary and delivering the entire flush marker first.
Z_FINISH closes the final block and writes the wrapper trailer.
Errors Z_BUF_ERROR covers zero output room, no possible progress with no input and
no stronger flush, or input offered after final-block processing began. It preserves a
live stream; provide room/input as appropriate. Z_STREAM_ERROR covers the stream check,
invalid flush (including Z_TREES), invalid NULL I/O combinations, or non-finish flush after
finishing began. Initial argument refusals consume no input or output. A later
Z_BUF_ERROR for new input after finishing may first deliver old pending output; no new
input is accepted. msg and remembered flush can change. The unchanged public goal
includes all signed flush values and these refusals.
Shared conditions and scope
API manual · Shared stream rules · Stream decompression
Use a z_stream compressor when input arrives in pieces, output space is limited, or you
need a chosen wrapper, dictionary or flush boundary. Initialize once, call deflate with
successive buffers, and end the stream even if compression is abandoned. For a single buffer,
see compress and compress2.
| Task | Entries |
|---|---|
| Start or reuse | Init, configured init, reset, reset retaining history |
| Supply metadata or history | Dictionary, read history, gzip header |
| Compress and size output | Deflate, bound, pending output, last flush bits |
| Adjust or branch | Parameters, tuning, priming, copy |
| Release storage | End |
These focused contracts follow the pinned deflate.c, applied patches and zlib.h in the
default LP64 Linux build. Source readings are to confirm by proof. They leave the broader
registered public goals unchanged. See contract conventions
for domain/effect labels and progress for proof status and remaining work.
Shared conventions
Each stated Pre requires termination without runtime faults and the stated Post. A call that retains a live stream preserves its representation invariant.
- Live stream: a writable
z_streamwith a compressor state established by successful init or copy, preserved by legal calls, and not ended. The caller does not alter its internal state or allocator fields. Calls on one stream are sequential. - Buffers: input covers
avail_inreadable bytes; output coversavail_outwritable bytes. They do not overlap each other, the stream or its owned state. A non-NULL scalar result points to a writable cell separate from other results and stream memory. These separation conditions are explicit focused assumptions; see safety.md. - Allocator: the default allocator/free pair is used, or both fields are NULL before init. Allocation may fail on any attempt. Custom allocator callbacks are outside this page's scope.
- Frame and ownership: calls change only their stream, its owned state and stated
output regions. Caller input is read-only. Caller buffers and header records remain caller-owned.
Only init and copy allocate; only their failure cleanup and
deflateEndfree memory. Other calls preserve the stream's allocation set. - Header lifetime: a retained gzip header and its optional fields remain readable and
unchanged while used. Non-NULL
nameandcommenthave a terminating zero;extracovers its stated length. Focused format contracts useextra_len <= 65535. - Checked refusals: except for init and bounds, a failed stream check returns
Z_STREAM_ERRORbefore normal operation, without writes.deflateCopyadditionally clears a non-NULL destination state. Query output cells are untouched on this refusal. - Restricted domain means these explicit memory, lifetime and call-order conditions, plus the entry's Pre. It does not mean every representable pointer or integer is accepted. Error summaries cover readable checked states, not arbitrary invalid addresses.
Formal contract
ZlibF.Spec.Public.Goal.deflate
Proof status: Not completed · Evidence and remaining work
/-- `int deflate(z_streamp strm, int flush)`.
Preserve the live stream and its five allocations. Account for exactly the bytes accepted
and delivered, including progress on a full output buffer and clean parameter refusals.
The sequence target states valid encoding, flush semantics and completion. -/
def Goal.deflate : Prop :=
∀ h r i z s flush,
StreamReachable .deflate h r → Zlib.Deflate.Spec.DGood h r i z s →
StreamBuffers h r → ActiveHeader h r →
∃ rc after z' s' used out,
C.run (Zlib.Deflate.deflate (some r) flush) h = .ok (rc, after) ∧
Zlib.Deflate.Spec.DGood after r i z' s' ∧ StreamAccounting z z' used out.length ∧
Bytes after z.next_out out.length out ∧
z'.total_in = z.total_in + UInt64.ofNat used ∧
z'.total_out = z.total_out + UInt64.ofNat out.length ∧
(rc = Z_OK ∨ rc = Z_STREAM_END ∨ rc = Z_STREAM_ERROR ∨ rc = Z_BUF_ERROR) ∧
(rc = Z_STREAM_ERROR ↔
flush.toInt < 0 ∨ 5 < flush.toInt ∨ z.next_out = .null ∨
(z.next_in = .null ∧ z.avail_in ≠ 0) ∨
(s.status = FINISH_STATE ∧ flush ≠ Z_FINISH)) ∧
(flush.toInt < 0 ∨ 5 < flush.toInt → rc = Z_STREAM_ERROR ∧ after = h) ∧
(rc = Z_STREAM_END → flush = Z_FINISH ∧ s'.status = FINISH_STATE ∧
z'.avail_in = 0 ∧ s'.pending = 0 ∧ s'.bi_valid = 0) ∧
BufferFrame h after (fun b => StreamRoot r b ∨ DeflateOwned i s b) [⟨z.next_out, out.length⟩] ∧
LiveChange h after (fun _ => False) (fun _ => False) ∧ after.nalloc = h.nallocRelated definitions and source ↗