![]() |
tinyimg 1.1.1
Lightweight image manipulation library for WebAssembly
|
DEFLATE and zlib streams, shared by the PNG and TIFF codecs. More...
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 11u |
| 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. | |
DEFLATE and zlib streams, shared by the PNG and TIFF codecs.
| #define TINY_DEFLATE_FAST_BITS 11u |
Bits the Huffman decoder resolves from one table lookup.
Longer codes fall back to walking the canonical code a bit at a time. The table 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.
Eleven rather than nine, and which file it helps is the point. Widening it measured 1.10x on forest.png (40.28 to 36.50 ms) and 1.01x on a 2400x1350 photograph. The two differ in how well they compress: forest is 3.74 MB of IDAT for 4.99 MB of pixels, so its literals carry long codes that a nine bit table misses, while the photograph compresses 10.9x and its codes were already covered. The win lands on the low-ratio files, which are the expensive ones. Twelve bits was worth a further 0.6% for twice the table and is not taken.
Costs 4 KiB of scratch per table against 1 KiB, and two are live at once, so 6 KiB of arena. Nothing holds one on the stack.
| #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 enum TinyDeflateLevel 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.
| enum 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.
| 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.
| data | The bytes to compress. |
| size | Number of bytes. |
| level | How hard to look for matches. |
| zlib | Non-zero to write a zlib header and Adler-32 trailer. |
| out | An initialized sink to append to. |
| 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.
| data | The compressed bytes. |
| size | Number of bytes. |
| zlib | Non-zero for a zlib wrapper. |
| out | An initialized sink to append to. |
| int tiny_inflate_finish | ( | TinyInflate * | state | ) |
Checks the stream ended cleanly, including a zlib trailer if there was a header.
| state | The stream. |
| 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.
| state | The stream. |
| data | The compressed bytes. |
| size | Number of bytes. |
| zlib | Non-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. |
| 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.
| state | The stream. |
| out | Where to put the bytes. |
| size | How many to read, at most TINY_DEFLATE_MAX_READ. |