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

Math shims, lookup table builders, checksums and bit level IO. More...

#include <stddef.h>
#include <stdint.h>

Go to the source code of this file.

Classes

struct  TinyWriter
 A grow on demand byte sink. More...
struct  TinyBitReader
 Reads a bitstream out of a byte buffer. More...
struct  TinyBitWriter
 Writes a bitstream into a TinyWriter. More...

Functions

float tiny_fabsf (float x)
 Absolute value of a float.
float tiny_sqrtf (float x)
 Square root of a float.
float tiny_floorf (float x)
 Largest integral value not greater than x.
float tiny_ceilf (float x)
 Smallest integral value not less than x.
float tiny_truncf (float x)
 Integral part of x, discarding the fraction.
float tiny_roundf (float x)
 Nearest integral value, halfway cases rounded away from zero.
float tiny_fmodf (float x, float y)
 Floating point remainder of x/y, with the sign of x.
float tiny_expf (float x)
 Exponential of x.
float tiny_logf (float x)
 Natural logarithm of x.
float tiny_powf (float x, float y)
 x raised to the power y.
float tiny_sinf (float x)
 Sine of x.
float tiny_cosf (float x)
 Cosine of x.
float tiny_atan2f (float y, float x)
 Angle of the vector (x, y) from the positive x axis.
void tiny_lut_identity (uint8_t *lut)
 Fills a 256 entry table with the identity mapping.
void tiny_lut_gamma (uint8_t *lut, float gamma)
 Fills a 256 entry table with a gamma curve.
void tiny_lut_srgb (uint8_t *lut, int encode)
 Fills a 256 entry table with the sRGB transfer function.
void tiny_lut_compose (uint8_t *out, const uint8_t *first, const uint8_t *second)
 Composes two 256 entry tables into one.
uint32_t tiny_crc32 (uint32_t crc, const uint8_t *data, size_t size)
 Computes a running CRC-32 over a buffer.
uint32_t tiny_adler32 (uint32_t adler, const uint8_t *data, size_t size)
 Computes a running Adler-32 over a buffer.
size_t tiny_strlen (const char *s)
 Length of a NUL terminated string.
int tiny_strcmp (const char *a, const char *b)
 Compares two NUL terminated strings.
int tiny_strcopy (char *dest, const char *src, size_t capacity)
 Copies a string into a fixed buffer, always terminating it.
int tiny_huffman_lengths (const uint32_t *frequencies, uint32_t count, uint32_t limit, uint8_t *lengths)
 Builds length limited Huffman code lengths from symbol frequencies.
int tiny_writer_init (TinyWriter *writer, size_t initial)
 Prepares a writer, optionally reserving space up front.
void tiny_writer_free (TinyWriter *writer)
 Releases a writer's buffer.
uint8_t * tiny_writer_detach (TinyWriter *writer, size_t *size)
 Detaches a writer's buffer, handing ownership to the caller.
int tiny_writer_reserve (TinyWriter *writer, size_t extra)
 Reserves capacity for at least extra more bytes.
int tiny_writer_write (TinyWriter *writer, const void *bytes, size_t size)
 Appends raw bytes.
int tiny_writer_fill (TinyWriter *writer, uint8_t value, size_t count)
 Appends the same byte repeatedly.
int tiny_writer_u8 (TinyWriter *writer, uint8_t value)
 Appends one byte.
int tiny_writer_le16 (TinyWriter *writer, uint16_t value)
 Appends a 16 bit value, little endian.
int tiny_writer_le32 (TinyWriter *writer, uint32_t value)
 Appends a 32 bit value, little endian.
int tiny_writer_be16 (TinyWriter *writer, uint16_t value)
 Appends a 16 bit value, big endian.
int tiny_writer_be32 (TinyWriter *writer, uint32_t value)
 Appends a 32 bit value, big endian.
uint32_t tiny_writer_sizeof (void)
 Size of a TinyWriter, for a host allocating one across the ABI.
uint8_t * tiny_writer_data (const TinyWriter *writer)
 Pointer to a writer's bytes.
uint32_t tiny_writer_size (const TinyWriter *writer)
 Number of bytes a writer holds.
void tiny_bits_init (TinyBitReader *reader, const uint8_t *data, size_t size)
 Points a bit reader at a buffer.
uint32_t tiny_bits_msb (TinyBitReader *reader, uint32_t count)
 Reads bits, most significant first.
uint32_t tiny_bits_peek_msb (TinyBitReader *reader, uint32_t count)
 Reads bits without consuming them, most significant first.
uint32_t tiny_bits_lsb (TinyBitReader *reader, uint32_t count)
 Reads bits, least significant first.
uint32_t tiny_bits_peek_lsb (TinyBitReader *reader, uint32_t count)
 Reads bits without consuming them, least significant first.
void tiny_bits_skip_msb (TinyBitReader *reader, uint32_t count)
 Discards bits already examined with a most significant first peek.
void tiny_bits_skip_lsb (TinyBitReader *reader, uint32_t count)
 Discards bits already examined with a least significant first peek.
void tiny_bits_align_msb (TinyBitReader *reader)
 Drops the partial byte at the read head of a most significant first stream.
void tiny_bits_align_lsb (TinyBitReader *reader)
 Drops the partial byte at the read head of a least significant first stream.
size_t tiny_bits_remaining (const TinyBitReader *reader)
 Bytes not yet consumed, counting only whole bytes past the head.
void tiny_bitwriter_init (TinyBitWriter *writer, TinyWriter *out)
 Points a bit writer at a byte sink.
void tiny_bitwriter_msb (TinyBitWriter *writer, uint32_t value, uint32_t count)
 Writes bits, most significant first.
void tiny_bitwriter_lsb (TinyBitWriter *writer, uint32_t value, uint32_t count)
 Writes bits, least significant first.
void tiny_bitwriter_flush_msb (TinyBitWriter *writer)
 Flushes a most significant bit first stream, padding with one bits.
void tiny_bitwriter_flush_lsb (TinyBitWriter *writer)
 Flushes a least significant bit first stream, padding with zero bits.

Detailed Description

Math shims, lookup table builders, checksums and bit level IO.

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

Function Documentation

◆ tiny_adler32()

uint32_t tiny_adler32 ( uint32_t adler,
const uint8_t * data,
size_t size )

Computes a running Adler-32 over a buffer.

Uses the zlib calling convention, so passing 1 for the first call produces the value a zlib stream trailer carries.

O(n) time complexity, where n is size.

Parameters
adlerRunning value, 1 to start a new checksum.
dataBytes to fold in. May be NULL when size is 0.
sizeNumber of bytes.
Returns
uint32_t The updated checksum.

◆ tiny_atan2f()

float tiny_atan2f ( float y,
float x )

Angle of the vector (x, y) from the positive x axis.

Parameters
yThe vertical component.
xThe horizontal component.
Returns
float Radians in (-pi, pi]. Both components zero gives zero.

◆ tiny_bits_align_lsb()

void tiny_bits_align_lsb ( TinyBitReader * reader)

Drops the partial byte at the read head of a least significant first stream.

DEFLATE needs this before a stored block's length field.

Parameters
readerThe reader.

◆ tiny_bits_align_msb()

void tiny_bits_align_msb ( TinyBitReader * reader)

Drops the partial byte at the read head of a most significant first stream.

JPEG needs this after a restart marker. The two orders keep their unread bits at opposite ends of the accumulator, so aligning is not a shared operation.

Parameters
readerThe reader.

◆ tiny_bits_init()

void tiny_bits_init ( TinyBitReader * reader,
const uint8_t * data,
size_t size )

Points a bit reader at a buffer.

Parameters
readerThe reader.
dataThe bytes.
sizeNumber of bytes.

◆ tiny_bits_lsb()

uint32_t tiny_bits_lsb ( TinyBitReader * reader,
uint32_t count )

Reads bits, least significant first.

Parameters
readerThe reader.
countHow many bits to read. Must be 24 or fewer.
Returns
uint32_t The bits, right aligned.

◆ tiny_bits_msb()

uint32_t tiny_bits_msb ( TinyBitReader * reader,
uint32_t count )

Reads bits, most significant first.

Parameters
readerThe reader.
countHow many bits to read. Must be 24 or fewer.
Returns
uint32_t The bits, right aligned.

◆ tiny_bits_peek_lsb()

uint32_t tiny_bits_peek_lsb ( TinyBitReader * reader,
uint32_t count )

Reads bits without consuming them, least significant first.

Parameters
readerThe reader.
countHow many bits to peek. Must be 24 or fewer.
Returns
uint32_t The bits, right aligned.

◆ tiny_bits_peek_msb()

uint32_t tiny_bits_peek_msb ( TinyBitReader * reader,
uint32_t count )

Reads bits without consuming them, most significant first.

Used by Huffman decoders, which look at the longest possible code and then skip only the bits the matched symbol actually used.

Parameters
readerThe reader.
countHow many bits to peek. Must be 24 or fewer.
Returns
uint32_t The bits, right aligned.

◆ tiny_bits_remaining()

size_t tiny_bits_remaining ( const TinyBitReader * reader)

Bytes not yet consumed, counting only whole bytes past the head.

Parameters
readerThe reader.
Returns
size_t The remaining byte count.

◆ tiny_bits_skip_lsb()

void tiny_bits_skip_lsb ( TinyBitReader * reader,
uint32_t count )

Discards bits already examined with a least significant first peek.

Parameters
readerThe reader.
countHow many bits to drop.

◆ tiny_bits_skip_msb()

void tiny_bits_skip_msb ( TinyBitReader * reader,
uint32_t count )

Discards bits already examined with a most significant first peek.

Parameters
readerThe reader.
countHow many bits to drop.

◆ tiny_bitwriter_flush_lsb()

void tiny_bitwriter_flush_lsb ( TinyBitWriter * writer)

Flushes a least significant bit first stream, padding with zero bits.

Parameters
writerThe bit writer.

◆ tiny_bitwriter_flush_msb()

void tiny_bitwriter_flush_msb ( TinyBitWriter * writer)

Flushes a most significant bit first stream, padding with one bits.

One bits are the padding JPEG entropy coded segments use.

Parameters
writerThe bit writer.

◆ tiny_bitwriter_init()

void tiny_bitwriter_init ( TinyBitWriter * writer,
TinyWriter * out )

Points a bit writer at a byte sink.

Parameters
writerThe bit writer.
outThe sink, which must outlive the bit writer.

◆ tiny_bitwriter_lsb()

void tiny_bitwriter_lsb ( TinyBitWriter * writer,
uint32_t value,
uint32_t count )

Writes bits, least significant first.

Parameters
writerThe bit writer.
valueThe bits, right aligned.
countHow many bits to write. Must be 24 or fewer.

◆ tiny_bitwriter_msb()

void tiny_bitwriter_msb ( TinyBitWriter * writer,
uint32_t value,
uint32_t count )

Writes bits, most significant first.

Parameters
writerThe bit writer.
valueThe bits, right aligned.
countHow many bits to write. Must be 24 or fewer.

◆ tiny_ceilf()

float tiny_ceilf ( float x)

Smallest integral value not less than x.

Parameters
xThe value.
Returns
float ceil(x).

◆ tiny_cosf()

float tiny_cosf ( float x)

Cosine of x.

Worst measured absolute error is 9.1e-8 over -20 to 20. Argument reduction uses a two part pi/2, which holds to roughly |x| < 1e5 radians.

Parameters
xThe angle in radians.
Returns
float cos(x).

◆ tiny_crc32()

uint32_t tiny_crc32 ( uint32_t crc,
const uint8_t * data,
size_t size )

Computes a running CRC-32 over a buffer.

Uses the reflected 0xEDB88320 polynomial and the zlib calling convention, so passing 0 for the first call produces the value PNG chunks and gzip trailers carry. The 1 KiB table is generated on first use rather than shipped.

O(n) time complexity, where n is size.

Parameters
crcRunning value, 0 to start a new checksum.
dataBytes to fold in. May be NULL when size is 0.
sizeNumber of bytes.
Returns
uint32_t The updated checksum.

◆ tiny_expf()

float tiny_expf ( float x)

Exponential of x.

Worst measured relative error is 2.2e-7 over -30 to 30, or two units in the last place. Saturates rather than producing subnormals: inputs above 87 return infinity and inputs below -87 return zero.

Parameters
xThe exponent.
Returns
float e raised to x.

◆ tiny_fabsf()

float tiny_fabsf ( float x)

Absolute value of a float.

Parameters
xThe value.
Returns
float |x|.

◆ tiny_floorf()

float tiny_floorf ( float x)

Largest integral value not greater than x.

Parameters
xThe value.
Returns
float floor(x).

◆ tiny_fmodf()

float tiny_fmodf ( float x,
float y )

Floating point remainder of x/y, with the sign of x.

Computed as x - y * trunc(x / y), so the result loses precision once |x / y| grows past the mantissa. Angles and other small ratios are unaffected.

Parameters
xThe dividend.
yThe divisor. Zero produces NaN.
Returns
float The remainder.

◆ tiny_huffman_lengths()

int tiny_huffman_lengths ( const uint32_t * frequencies,
uint32_t count,
uint32_t limit,
uint8_t * lengths )

Builds length limited Huffman code lengths from symbol frequencies.

Shared by every encoder that writes a prefix code, which is DEFLATE for its literals, its distances and its own code length alphabet, and WebP lossless for all five of its alphabets. They differ only in how many symbols they have and how deep a code they can express.

The lengths are canonical: the caller turns them into codes, and a symbol whose frequency is zero gets a length of zero and no code. An alphabet with one used symbol gets that symbol a length of one, which a canonical builder can express and which the two formats then treat differently.

O(n^2) time complexity in the alphabet size, because the two lowest weight nodes are found by scanning rather than through a heap. At the 536 symbols the larger caller reaches that is about 143k comparisons, against a heap's 5k, and it is a third of the code; past a few thousand symbols the trade stops being worth it, which is one reason WebP's color cache is capped where it is.

Parameters
frequenciesHow often each symbol occurs, count entries.
countSymbols in the alphabet.
limitLongest code the format can express, in bits.
lengthsReceives count lengths, zero for an unused symbol.
Returns
int TINYIMG_OK, TINYIMG_ERR_NULL, TINYIMG_ERR_RANGE for a zero count or limit, or TINYIMG_ERR_MEMORY when the arena has no room for the tree.

◆ tiny_logf()

float tiny_logf ( float x)

Natural logarithm of x.

Worst measured error over 1e-6 to 1e6 is 5.8e-7 absolute and 2.4e-7 relative. Relative error is unbounded as the result approaches zero at x = 1, which is a property of the function rather than of this implementation, so the absolute figure is the useful one. Subnormal inputs are handled by scaling.

Parameters
xThe value. Zero returns negative infinity and negatives return NaN.
Returns
float The natural log of x.

◆ tiny_lut_compose()

void tiny_lut_compose ( uint8_t * out,
const uint8_t * first,
const uint8_t * second )

Composes two 256 entry tables into one.

The result applies first and then second, which is what lets a chain of point operations collapse into a single table.

Parameters
outTable to fill. May alias first, since each entry is read before it is written; aliasing second reads entries that have already been overwritten.
firstThe table applied first.
secondThe table applied second.

◆ tiny_lut_gamma()

void tiny_lut_gamma ( uint8_t * lut,
float gamma )

Fills a 256 entry table with a gamma curve.

Values above 1 darken the midtones and values below 1 brighten them, matching the sense of tiny_image_gamma_correction.

Parameters
lutTable to fill.
gammaThe exponent. Values at or below zero leave the table as the identity.

◆ tiny_lut_identity()

void tiny_lut_identity ( uint8_t * lut)

Fills a 256 entry table with the identity mapping.

Parameters
lutTable to fill.

◆ tiny_lut_srgb()

void tiny_lut_srgb ( uint8_t * lut,
int encode )

Fills a 256 entry table with the sRGB transfer function.

The piecewise curve from IEC 61966-2-1, linear near black and a power of 1/2.4 above it, rather than the plain 2.2 power it is often quoted as. The two differ by up to three levels in the shadows, which is where an ICC conversion is measured.

Parameters
lutTable to fill.
encodeNon-zero for linear light to sRGB, zero for the inverse.

◆ tiny_powf()

float tiny_powf ( float x,
float y )

x raised to the power y.

Evaluated as exp(y * log(x)), so the relative error grows with |y * log(x)|. Worst measured relative error is 1.3e-6 at an exponent of 2.2 over 0 to 1, which is the gamma case; that is a quarter of one step of an 8 bit channel. A negative base is only defined for integral exponents and returns NaN otherwise.

Parameters
xThe base.
yThe exponent.
Returns
float x to the power y.

◆ tiny_roundf()

float tiny_roundf ( float x)

Nearest integral value, halfway cases rounded away from zero.

Parameters
xThe value.
Returns
float round(x).

◆ tiny_sinf()

float tiny_sinf ( float x)

Sine of x.

Worst measured absolute error is 9.1e-8 over -20 to 20. Argument reduction uses a two part pi/2, which holds to roughly |x| < 1e5 radians.

Parameters
xThe angle in radians.
Returns
float sin(x).

◆ tiny_sqrtf()

float tiny_sqrtf ( float x)

Square root of a float.

Parameters
xThe value. Negative inputs produce NaN.
Returns
float The square root of x.

◆ tiny_strcmp()

int tiny_strcmp ( const char * a,
const char * b )

Compares two NUL terminated strings.

Parameters
aFirst string.
bSecond string.
Returns
int Zero when equal, otherwise the signed difference of the first differing byte.

◆ tiny_strcopy()

int tiny_strcopy ( char * dest,
const char * src,
size_t capacity )

Copies a string into a fixed buffer, always terminating it.

Truncates rather than overrunning when the source does not fit.

Parameters
destDestination buffer.
srcSource string.
capacitySize of dest in bytes, including the terminator.
Returns
int TINYIMG_OK, or TINYIMG_ERR_BUFFER_TOO_SMALL when src was truncated.

◆ tiny_strlen()

size_t tiny_strlen ( const char * s)

Length of a NUL terminated string.

Parameters
sThe string.
Returns
size_t The number of bytes before the terminator, or 0 if s is NULL.

◆ tiny_truncf()

float tiny_truncf ( float x)

Integral part of x, discarding the fraction.

Parameters
xThe value.
Returns
float trunc(x).

◆ tiny_writer_be16()

int tiny_writer_be16 ( TinyWriter * writer,
uint16_t value )

Appends a 16 bit value, big endian.

Parameters
writerThe writer.
valueThe value.
Returns
int TINYIMG_OK or a negative TinyImageError.

◆ tiny_writer_be32()

int tiny_writer_be32 ( TinyWriter * writer,
uint32_t value )

Appends a 32 bit value, big endian.

Parameters
writerThe writer.
valueThe value.
Returns
int TINYIMG_OK or a negative TinyImageError.

◆ tiny_writer_data()

uint8_t * tiny_writer_data ( const TinyWriter * writer)

Pointer to a writer's bytes.

Parameters
writerThe writer.
Returns
uint8_t* The buffer, or NULL when nothing has been written.

◆ tiny_writer_detach()

uint8_t * tiny_writer_detach ( TinyWriter * writer,
size_t * size )

Detaches a writer's buffer, handing ownership to the caller.

The writer is left empty. The caller releases the buffer with tiny_free.

Parameters
writerThe writer.
sizeReceives the byte length.
Returns
uint8_t* The buffer, or NULL when the writer holds an error.

◆ tiny_writer_fill()

int tiny_writer_fill ( TinyWriter * writer,
uint8_t value,
size_t count )

Appends the same byte repeatedly.

Parameters
writerThe writer.
valueThe byte.
countHow many times to append it.
Returns
int TINYIMG_OK or a negative TinyImageError.

◆ tiny_writer_free()

void tiny_writer_free ( TinyWriter * writer)

Releases a writer's buffer.

Parameters
writerThe writer. Safe to call twice.

◆ tiny_writer_init()

int tiny_writer_init ( TinyWriter * writer,
size_t initial )

Prepares a writer, optionally reserving space up front.

Parameters
writerThe writer.
initialBytes to reserve. Zero defers the first allocation to the first write.
Returns
int TINYIMG_OK or a negative TinyImageError.

◆ tiny_writer_le16()

int tiny_writer_le16 ( TinyWriter * writer,
uint16_t value )

Appends a 16 bit value, little endian.

Parameters
writerThe writer.
valueThe value.
Returns
int TINYIMG_OK or a negative TinyImageError.

◆ tiny_writer_le32()

int tiny_writer_le32 ( TinyWriter * writer,
uint32_t value )

Appends a 32 bit value, little endian.

Parameters
writerThe writer.
valueThe value.
Returns
int TINYIMG_OK or a negative TinyImageError.

◆ tiny_writer_reserve()

int tiny_writer_reserve ( TinyWriter * writer,
size_t extra )

Reserves capacity for at least extra more bytes.

Parameters
writerThe writer.
extraAdditional bytes needed.
Returns
int TINYIMG_OK or a negative TinyImageError.

◆ tiny_writer_size()

uint32_t tiny_writer_size ( const TinyWriter * writer)

Number of bytes a writer holds.

Parameters
writerThe writer.
Returns
uint32_t The byte length.

◆ tiny_writer_sizeof()

uint32_t tiny_writer_sizeof ( void )

Size of a TinyWriter, for a host allocating one across the ABI.

Returns
uint32_t sizeof(TinyWriter).

◆ tiny_writer_u8()

int tiny_writer_u8 ( TinyWriter * writer,
uint8_t value )

Appends one byte.

Parameters
writerThe writer.
valueThe byte.
Returns
int TINYIMG_OK or a negative TinyImageError.

◆ tiny_writer_write()

int tiny_writer_write ( TinyWriter * writer,
const void * bytes,
size_t size )

Appends raw bytes.

Parameters
writerThe writer.
bytesSource buffer.
sizeNumber of bytes.
Returns
int TINYIMG_OK or a negative TinyImageError.