brotli clib Compression / Web

Google's Brotli compression for PascalAI. 20–26% better ratio than gzip with native browser support (Content-Encoding: br). Quality levels 0–11 from real-time streaming to best-ratio static asset pre-compression.

ppm install brotli

Overview

brotli wraps libbrotli — Google's open-source lossless compression algorithm designed for the modern web. All major browsers support it natively via the Accept-Encoding: br / Content-Encoding: br HTTP header pair, making it the preferred format for serving compressed web content.

The library offers both one-shot functions for simple in-memory compression and streaming encoder/decoder handles for processing large inputs in chunks without buffering everything in RAM.

CLib package

Requires libbrotli-dev. Ubuntu/Debian: sudo apt install libbrotli-dev

Quality Levels

Brotli quality ranges from 0 (fastest, weakest) to 11 (slowest, best ratio). Choose based on your latency vs. size trade-off.

QualityProfileTypical use
0–1Very fast — comparable to gzip -1Real-time API responses, live streams
2–3FastHigh-throughput servers with CPU constraints
4–6Balanced (default = 6)General-purpose web serving, most deployments
7–8Good ratioBatch compression jobs, build pipelines
9–11Best ratio, slow encodePre-compressing static assets (HTML, JS, CSS, fonts)
Tip — pre-compress static files at quality 11

Encode once with CompressBest and store the .br files. nginx and Apache serve them directly with zero per-request CPU cost via brotli_static on.

vs. Other Algorithms

Algorithmvs. BrotliBest fit
gzipBrotli has 20–26% better ratio; similar or faster decodeLegacy clients, S3/CDN defaults
zstdSimilar ratio; zstd encodes faster; brotli better native browser supportDatabases, internal services
lzmaBrotli decodes much faster; lzma wins on ratio for archivesInstallers, archive distribution

Quick Start

Compress and decompress in one call

uses brotli;

var html := '<!DOCTYPE html><html>...</html>';

{ Quality 6, generic mode }
var compressed := Compress(html, 6, bmGeneric);
WriteLn('Compressed: ' + IntToStr(Length(compressed)) + ' bytes');

var ratio := CompressionRatio(html, compressed);
WriteLn('Ratio: ' + FloatToStr(ratio));

var restored := Decompress(compressed);
WriteLn('Restored: ' + IntToStr(Length(restored)) + ' bytes');

Default and convenience shortcuts

uses brotli;

{ quality=6, bmGeneric — good for most cases }
var data := CompressDefault(payload);

{ quality=11 — slowest, best ratio, ideal for static assets }
var small := CompressBest(payload, bmText);

{ quality=1 — fastest encode }
var fast := CompressFast(payload);

Compress a file to .br

uses brotli;

{ Pre-compress a JS bundle at best quality for nginx brotli_static }
CompressFile('/var/www/app.js', '/var/www/app.js.br', 11, bmGeneric);

{ Decompress later }
DecompressFile('/var/www/app.js.br', '/tmp/app.js');

One-Shot API

Use these functions when the entire input fits comfortably in memory. For large files or network streams, prefer the Streaming API below.

FunctionDescription
Compress(Data, Quality, Mode)Compress string with explicit quality (0–11) and mode. Returns compressed bytes as string.
CompressDefault(Data)Compress with quality 6 and bmGeneric mode.
CompressBest(Data, Mode)Compress at quality 11 (best ratio, slower encode).
CompressFast(Data)Compress at quality 1 (fastest encode).
Decompress(Data)Decompress brotli-compressed bytes. Raises on corrupt input.
CompressFile(SrcPath, DstPath, Quality, Mode)Compress a file in place to a .br output path.
DecompressFile(SrcPath, DstPath)Decompress a .br file to the destination path.

Streaming Encoder API

Feed data in chunks to the encoder — useful when compressing network streams, large log files, or any source where the full input is not known upfront. Call FinishEncoder to flush the final compressed block.

uses brotli;

var enc := NewEncoder(6, bmText);

var i := 0;
while i < Length(chunks) do
begin
  EncodeChunk(enc, chunks[i]);
  { FlushEncoder sends partial output without finishing the stream }
  var partial := FlushEncoder(enc);
  if Length(partial) > 0 then
    SendToClient(partial);
  i := i + 1;
end;

{ Finish produces the final compressed bytes }
var tail := FinishEncoder(enc);
SendToClient(tail);
FreeEncoder(enc);
FunctionDescription
NewEncoder(Quality, Mode)Create a streaming encoder handle. Returns a TBrotliState.
FreeEncoder(E)Release encoder resources. Always call when done.
EncodeChunk(E, Data)Feed a chunk of uncompressed data to the encoder.
FlushEncoder(E)Flush buffered output and return partial compressed bytes (for live streaming).
FinishEncoder(E)Signal end of input and return the final compressed bytes. Must be called once.

Streaming Decoder API

Decompress data arriving in chunks — for example, reading a compressed HTTP response body as it arrives over the network.

uses brotli;

var dec := NewDecoder();

var chunk := ReadNextChunk();
while chunk <> '' do
begin
  var out := DecodeChunk(dec, chunk);
  if Length(out) > 0 then
    ProcessOutput(out);
  chunk := ReadNextChunk();
end;

if DecoderDone(dec) then
  WriteLn('Stream fully decoded');

FreeDecoder(dec);
FunctionDescription
NewDecoder()Create a streaming decoder handle.
FreeDecoder(D)Release decoder resources.
DecodeChunk(D, Data)Feed a compressed chunk. Returns any decompressed bytes available so far.
DecoderDone(D)Returns True when all input has been consumed and output is complete.

Utilities API

FunctionDescription
MaxCompressedSize(InputSize)Estimate the worst-case compressed output size for InputSize bytes. Use to pre-allocate buffers.
IsBrotli(Data)Heuristic check — returns True if the data looks like a brotli stream. Not a full validation.
CompressionRatio(Original, Compressed)Returns compressed_size / original_size as a Double. Values below 1.0 indicate compression savings.
BrotliVersion()Returns the linked libbrotli version string.
uses brotli;

WriteLn('libbrotli ' + BrotliVersion());

var maxBuf := MaxCompressedSize(1024 * 1024);  { worst case for 1 MB input }
WriteLn('Max output buffer: ' + IntToStr(maxBuf) + ' bytes');

var raw := ReadFile('data.bin');
if IsBrotli(raw) then
  raw := Decompress(raw);

Types

TBrotliState

An opaque integer handle returned by NewEncoder and NewDecoder. Pass it to the corresponding chunk/flush/finish/free functions. Do not share a single state between concurrent goroutines or threads without external locking.

type
  TBrotliState = Integer;  { streaming encoder/decoder handle }

TBrotliMode

Hints to the encoder about the nature of the input data. Using the right mode can improve both compression ratio and speed.

type
  TBrotliMode = (
    bmGeneric = 0,  { default — works for all data }
    bmText    = 1,  { optimized for UTF-8 text }
    bmFont    = 2   { optimized for WOFF 2.0 fonts }
  );
ModeUse when
bmGenericBinary data, mixed content, or unknown input type
bmTextHTML, CSS, JavaScript, JSON, plain text (UTF-8)
bmFontWOFF 2.0 web font files — yields meaningful extra savings

Key Concepts

Web compression workflow

The canonical deployment pattern is to pre-compress all static assets at build time with quality 11 and serve them with a Content-Encoding: br header. Nginx example: brotli_static on;. For dynamic responses (API payloads, SSR HTML) compress on-the-fly at quality 4–6 to keep latency low.

HTTP header negotiation

Clients advertise support with Accept-Encoding: br, gzip. Your server should check for br first and fall back to gzip for older clients. The IsBrotli utility can help detect the encoding of cached or stored blobs.

Memory note — streaming vs. one-shot

One-shot functions (Compress, Decompress) buffer the full output in memory. For inputs larger than a few megabytes, use NewEncoder / NewDecoder to keep memory usage bounded.

Package Info

Version1.0.0
Typeclib
C Librarylibbrotli-dev
Authorgustavo

System Requirements

libbrotli-dev

Ubuntu/Debian:
sudo apt install libbrotli-dev

TBrotliMode

bmGeneric — all data types
bmText — UTF-8 text
bmFont — WOFF 2.0 fonts

Functions

  • Compress
  • CompressDefault
  • CompressBest
  • CompressFast
  • Decompress
  • CompressFile
  • DecompressFile
  • NewEncoder / FreeEncoder
  • EncodeChunk
  • FlushEncoder
  • FinishEncoder
  • NewDecoder / FreeDecoder
  • DecodeChunk
  • DecoderDone
  • MaxCompressedSize
  • IsBrotli
  • CompressionRatio
  • BrotliVersion

See Also