tinyimg 1.0.0
Lightweight image manipulation library for Cloudflare Workers
Loading...
Searching...
No Matches
deflate.h File Reference

DEFLATE and zlib streams, shared by the PNG and TIFF codecs. More...

#include <stddef.h>
#include <stdint.h>
#include "tinyimg/tinyimg.h"
#include "tinyimg/util.h"

Go to the source code of this file.

Classes

struct  TinyHuffman
 A canonical Huffman decode table. More...
struct  TinyInflate
 A DEFLATE stream being read. More...

Macros

#define TINY_DEFLATE_WINDOW   32768u
 Bytes of history a back reference can reach, which RFC 1951 fixes at 32 KiB.
#define TINY_DEFLATE_FAST_BITS   9u
 Bits the Huffman decoder resolves from one table lookup.
#define TINY_DEFLATE_MAX_READ   (TINY_DEFLATE_WINDOW - 258u)
 Most bytes a single read may ask for.

Typedefs

typedef enum TinyDeflateLevel TinyDeflateLevel
 How hard the compressor should look for matches.

Enumerations

enum  TinyDeflateLevel { TINYIMG_DEFLATE_HUFFMAN = 0 , TINYIMG_DEFLATE_FAST = 1 , TINYIMG_DEFLATE_DEFAULT = 2 , TINYIMG_DEFLATE_BEST = 3 }
 How hard the compressor should look for matches. More...

Functions

int tiny_inflate_init (TinyInflate *state, const uint8_t *data, size_t size, int zlib)
 Prepares a stream for reading.
long tiny_inflate_read (TinyInflate *state, uint8_t *out, size_t size)
 Reads decompressed bytes, producing only as many as are asked for.
int tiny_inflate_finish (TinyInflate *state)
 Checks the stream ended cleanly, including a zlib trailer if there was a header.
int tiny_inflate_all (const uint8_t *data, size_t size, int zlib, TinyWriter *out)
 Decompresses a whole stream into a growing sink.
int tiny_deflate (const uint8_t *data, size_t size, TinyDeflateLevel level, int zlib, TinyWriter *out)
 Compresses a buffer into a growing sink.

Detailed Description

DEFLATE and zlib streams, shared by the PNG and TIFF codecs.

Author
Gregory Mitchell (me@gm.nosp@m.itch.nosp@m.215.x.nosp@m.yz)
Version
1.0.0
Date
2026-09-02

Macro Definition Documentation

◆ TINY_DEFLATE_FAST_BITS

#define TINY_DEFLATE_FAST_BITS   9u

Bits the Huffman decoder resolves from one table lookup.

Nine covers the overwhelming majority of codes in a real stream; longer ones fall back to walking the canonical code a bit at a time. A table this size costs 1 KiB of scratch and turns a per symbol loop of about eight iterations into a single index, which is the difference between meeting the throughput target for PNG and missing it several times over.

◆ TINY_DEFLATE_MAX_READ

#define TINY_DEFLATE_MAX_READ   (TINY_DEFLATE_WINDOW - 258u)

Most bytes a single read may ask for.

The window is a ring, and a match can add 258 bytes past what the caller asked for, so a request has to leave that much room. A caller wanting more loops.

Typedef Documentation

◆ TinyDeflateLevel

How hard the compressor should look for matches.

These order by effort, not by output size. A level that searches harder usually produces less, but not always: measured on a photograph's filtered PNG rows, TINYIMG_DEFLATE_HUFFMAN beats TINYIMG_DEFLATE_FAST, because taking one short match per position disturbs the byte distribution more than the match saves. TINYIMG_DEFLATE_DEFAULT and above are past that and monotonic.

Enumeration Type Documentation

◆ TinyDeflateLevel

How hard the compressor should look for matches.

These order by effort, not by output size. A level that searches harder usually produces less, but not always: measured on a photograph's filtered PNG rows, TINYIMG_DEFLATE_HUFFMAN beats TINYIMG_DEFLATE_FAST, because taking one short match per position disturbs the byte distribution more than the match saves. TINYIMG_DEFLATE_DEFAULT and above are past that and monotonic.

Enumerator
TINYIMG_DEFLATE_HUFFMAN 

Entropy code the input without searching for matches at all.

Not a stored block: literals are still Huffman coded, so redundancy in the byte distribution is still taken. The floor for anything already compressed.

TINYIMG_DEFLATE_FAST 

One hash chain probe per position, no lazy matching.

TINYIMG_DEFLATE_DEFAULT 

A bounded chain walk with lazy matching, which is the default.

TINYIMG_DEFLATE_BEST 

A long chain walk, for when output size matters more than time.

Function Documentation

◆ tiny_deflate()

int tiny_deflate ( const uint8_t * data,
size_t size,
TinyDeflateLevel level,
int zlib,
TinyWriter * out )

Compresses a buffer into a growing sink.

Emits dynamic Huffman blocks, falling back to a stored block whenever that would be smaller, so incompressible input never grows by more than the five byte block header.

Takes its match tables from the arena, so the caller marks and releases around the call.

Parameters
dataThe bytes to compress.
sizeNumber of bytes.
levelHow hard to look for matches.
zlibNon-zero to write a zlib header and Adler-32 trailer.
outAn initialized sink to append to.
Returns
int TINYIMG_OK or a negative TinyImageError.

◆ tiny_inflate_all()

int tiny_inflate_all ( const uint8_t * data,
size_t size,
int zlib,
TinyWriter * out )

Decompresses a whole stream into a growing sink.

For callers with no reason to stream, such as a TIFF strip.

Parameters
dataThe compressed bytes.
sizeNumber of bytes.
zlibNon-zero for a zlib wrapper.
outAn initialized sink to append to.
Returns
int TINYIMG_OK or a negative TinyImageError.

◆ tiny_inflate_finish()

int tiny_inflate_finish ( TinyInflate * state)

Checks the stream ended cleanly, including a zlib trailer if there was a header.

Parameters
stateThe stream.
Returns
int TINYIMG_OK, or TINYIMG_ERR_CORRUPT for a truncated stream or a bad checksum.

◆ tiny_inflate_init()

int tiny_inflate_init ( TinyInflate * state,
const uint8_t * data,
size_t size,
int zlib )

Prepares a stream for reading.

Takes its window and Huffman tables from the arena, so the caller marks the arena before this and releases afterwards rather than freeing anything by hand.

Parameters
stateThe stream.
dataThe compressed bytes.
sizeNumber of bytes.
zlibNon-zero to consume a two byte zlib header and verify the Adler-32 trailer, which is what PNG's IDAT and TIFF's Deflate both carry; zero for a bare DEFLATE stream.
Returns
int TINYIMG_OK, TINYIMG_ERR_MEMORY, or TINYIMG_ERR_CORRUPT for a bad zlib header.

◆ tiny_inflate_read()

long tiny_inflate_read ( TinyInflate * state,
uint8_t * out,
size_t size )

Reads decompressed bytes, producing only as many as are asked for.

Returns fewer than requested at the end of the stream, and zero once it is exhausted. A caller wanting a fixed length loops until it has it or the count comes back zero.

Parameters
stateThe stream.
outWhere to put the bytes.
sizeHow many to read, at most TINY_DEFLATE_MAX_READ.
Returns
long Bytes produced, or a negative TinyImageError.