inflate
Consume compressed bytes and write decoded bytes, preserving state across calls.
Full chapter and shared rules ↗ecafc184cdf44b7f · 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 inflate(z_streamp strm, int flush);
Consume compressed bytes and write decoded bytes, preserving state across calls.
Domain Restricted domain: live streams with common buffer/header lifetimes;
arbitrary compressed bytes, input/output splits and signed flush values.
Effects Mutates stream, output and registered header storage; may allocate the history window.
Pre next_in describes avail_in readable bytes and may be NULL only when
that count is zero. next_out is non-NULL even for zero avail_out, and describes
that many writable bytes. A registered header and its buffers remain writable.
Calls may continue with more input/room, supply a requested dictionary, or follow
successful reset/recovery. Terminal/error repeats have the behavior below.
Post Reads/writes within the stated ranges. Advances pointers and reduces
available counts by bytes consumed/produced. In an ordinary run from init/reset,
with a valid selected format and the correct dictionary, accumulated output is a
prefix of the decoded data and equals it at Z_STREAM_END. Malformed bytes are
part of the domain: detected format or enabled checksum/length failures return
Z_DATA_ERROR, possibly after output. Incomplete input alone needs more input;
it need not be reported as a data error.
| Result | Meaning and next action |
|---|---|
Z_OK |
Made input or output progress; continue with available input/room |
Z_STREAM_END |
Finished one stream/member, including enabled trailer checks; trailing input remains |
Z_NEED_DICT |
Zlib dictionary required; adler is its identifier; set the dictionary |
Z_BUF_ERROR |
No progress, or Z_FINISH could not complete; provide input/room |
Z_DATA_ERROR |
Detected malformed data; reset, recover or end |
Z_MEM_ERROR |
Window allocation failed; reset or end |
Z_STREAM_ERROR |
Stream/buffer check failed, or recovery search is unfinished |
Accounting Normal returns, including data and buffer errors, update totals by
consumed/produced bytes and update the enabled output checksum. Z_NEED_DICT
accounts for consumed header bytes and leaves adler as the dictionary identifier.
A late window-allocation failure can follow input consumption and output writes:
pointers/counts already reflect them, but normal final total/checksum/data_type
accounting is skipped. Do not treat Z_MEM_ERROR as an unchanged-output result.
Edges Zero input or output room is allowed. Z_BLOCK stops at a header or
block boundary; Z_TREES also stops after block descriptions. Z_FINISH changes an
otherwise Z_OK result to Z_BUF_ERROR. Other signed flush values are accepted
and behave like Z_NO_FLUSH. data_type on normal returns records unused bits,
plus 64 for the last block, 128 at a header/block boundary, and 256 after a block
header. Data and memory errors are sticky; completed streams repeat Z_STREAM_END.
Ownership New window storage belongs to the stream and remains available for
reset/end, including after errors. A one-call Z_FINISH completion may need no
window. Concatenated gzip members require reset between members. Error messages
are borrowed static strings. Buffer and stream check refusals change nothing.
Shared conditions and scope
API manual · Shared stream rules · Stream compression
Use an inflate stream to decode input in pieces while controlling output space. Select zlib,
gzip or raw DEFLATE at initialization, then continue with more input or room until completion,
a dictionary request or an error. End releases the decoder after any of those outcomes.
For whole-buffer zlib decoding, see uncompress.
| Task | Entries |
|---|---|
| Start or reuse | Init, configured init, reset, new configuration, keep history |
| Decode or provide metadata | Inflate, set dictionary, read history, gzip header |
| Recover or inspect | Sync search, sync point, mark, table use |
| Adjust or branch | Prime bits, validation, distance option, copy |
| Release storage | End |
The focused contracts follow the pinned inflate.c and zlib.h in the default LP64 Linux
build, with gzip enabled and without optional invalid-distance or strict-distance modes.
Source readings are to confirm by proof. The broader registered public goals
retain their domains. See contract conventions for terminology and
progress for proof status and remaining work.
Common conditions
All contracts below have a Restricted domain. A C pointer type alone does not supply the storage, lifetime or call history required here.
- A live stream was successfully initialised or copied, has not been ended, retains its library-owned state, and is used without concurrent calls. Use the default allocator and free function. Init takes a writable, non-live stream with allocator fields set to NULL or the default functions.
- A readable or writable range has the stated capacity for the whole call. Caller ranges are separate from the stream and its owned storage. Input and output ranges do not overlap. Dictionary destinations, the registered header record and its destination buffers are separate from each other and from the stream. Registered header storage is also separate from input/output ranges on calls using it. These are explicit focused-domain restrictions.
- The caller owns its stream object and buffers. The library owns the state and optional window. A call changes only its stream, owned storage, stated output ranges and any registered header destination. It never frees caller buffers.
- A rejected stream check returns
Z_STREAM_ERRORwithout changes, unless a query or copy contract says otherwise. This covers NULL and safely readable records rejected by the check; it does not cover dangling or arbitrary pointers. The check requires allocators, state, the state's back-pointer and a valid mode. - Counters use the C unsigned widths and wrap. No contract assumes allocation succeeds. End remains available after decoding, dictionary or allocation errors.
flowchart LR
I["Init"] --> F["inflate"]
F -->|"Z_NEED_DICT"| D["SetDictionary"] --> F
F -->|"more room or input"| F
F -->|"end or abandon"| E["End"]
F -->|"data error"| R["Reset or Sync"] --> F
Formal contract
ZlibF.Spec.Public.Goal.inflate
Proof status: Not completed · Evidence and remaining work
/-- `int inflate(z_streamp strm, int flush)`.
The domain is actual init/call history, not an arbitrary hand-built decoder state.
The selected LP64 platform scope explicitly requires every live represented
byte object to have at most PTRDIFF_MAX bytes (size < 2^63), including caller
storage from non-malloc origins. See docs/deviations.md.
Includes all signed flush arguments, progress, terminal/error modes, output bounds,
counter timing on late memory failure, caller frame and ownership of a new window.
The sequence target states format correctness across all input/output splits. -/
def Goal.inflate : Prop :=
∀ h r i z s flush,
StreamReachable .inflate h r → Zlib.Inflate.Spec.Good h r i z s →
ZlibF.PlatformMemory.ByteObjectsFit h →
Zlib.Inflate.Spec.DefAlloc z → StreamBuffers h r → ActiveHeader h r →
∃ rc after z' s' used out,
C.run (Zlib.Inflate.inflate (some r) flush) h = .ok (rc, after) ∧
Zlib.Inflate.Spec.Good after r i z' s' ∧ StreamAccounting z z' used out.length ∧
Bytes after z.next_out out.length out ∧
(rc = Z_OK ∨ rc = Z_STREAM_END ∨ rc = Z_NEED_DICT ∨ rc = Z_STREAM_ERROR ∨
rc = Z_DATA_ERROR ∨ rc = Z_MEM_ERROR ∨ rc = Z_BUF_ERROR) ∧
(rc = Z_OK → (used ≠ 0 ∨ out ≠ []) ∧ flush ≠ Z_FINISH) ∧
(rc = Z_STREAM_END → s'.mode = DONE) ∧
(rc = Z_NEED_DICT → s'.mode = DICT) ∧
(rc = Z_DATA_ERROR → s'.mode = BAD) ∧
(rc = Z_MEM_ERROR → s'.mode = MEM ∧ z'.total_in = z.total_in ∧ z'.total_out = z.total_out) ∧
(rc = Z_OK ∨ rc = Z_STREAM_END ∨ rc = Z_DATA_ERROR ∨ rc = Z_BUF_ERROR →
z'.total_in = z.total_in + UInt64.ofNat used ∧
z'.total_out = z.total_out + UInt64.ofNat out.length) ∧
BufferFrame h after
(fun b => StreamRoot r b ∨ InflateOwned i s b ∨ s.head = some (.tab b))
(⟨z.next_out, out.length⟩ :: HeaderRegions h s.head) ∧
LiveChange h after (fun b => InflateOwned i s' b ∧ ¬ h.live b) (fun _ => False)Related definitions and source ↗