package core:compress/deflate

⌘K
Ctrl+K
or
/

    Overview

    Deflate compression and decompression implementation, following RFC 1950 (zlib), RFC 1951 (DEFLATE), and RFC 1952 (gzip).

    This is a hardened, extended, and optimized port of Micha Mettke's sinfl.h + sdefl.h, which we based this work on, with thanks.

    Index

    Constants (46)
    `#config` values (1)

    Types

    Deflate ¶

    Deflate :: struct {
    	bit_buffer:     i32,
    	bit_count:      i32,
    	hash_head:      [32768]i32,
    	hash_chain:     [32768]i32,
    	sequence_count: i32,
    	sequences:      [32770]Deflate_Sequence,
    	frequencies:    Deflate_Frequency,
    	codes:          Deflate_Codes,
    	hash3_head:     [4096]i32,
    }
     

    This struct is ~540kiB: allocate it with new rather than on the stack.

    Related Procedures With Parameters

    Deflate_Block_Type ¶

    Deflate_Block_Type :: enum int {
    	Stored, 
    	Dynamic, 
    	Fixed, 
    }

    Deflate_Code_Words ¶

    Deflate_Code_Words :: struct {
    	literal:  [288]u32,
    	distance: [32]u32,
    }

    Deflate_Codes ¶

    Deflate_Codes :: struct {
    	words:   Deflate_Code_Words,
    	lengths: Deflate_Lengths,
    }

    Deflate_Frequency ¶

    Deflate_Frequency :: struct {
    	literal:  [288]u32,
    	distance: [32]u32,
    }

    Deflate_Lengths ¶

    Deflate_Lengths :: struct {
    	literal:  [288]u8,
    	distance: [32]u8,
    }

    Deflate_Level ¶

    Deflate_Level :: enum i32 {
    	Stored   = 0, 
    	Level_1  = 1, 
    	Level_2  = 2, 
    	Level_3  = 3, 
    	Level_4  = 4, 
    	Level_5  = 5, 
    	Level_6  = 6, 
    	Level_7  = 7, 
    	Level_8  = 8, 
    	Level_9  = 9, 
    	Level_10 = 10, 
    	Fastest  = Level_1, 
    	Default  = Level_6, 
    	Best     = Level_10, 
    }

    Related Procedures With Parameters

    Related Constants

    Deflate_Match ¶

    Deflate_Match :: struct {
    	distance: i32,
    	length:   i32,
    }

    Deflate_Match_Codes ¶

    Deflate_Match_Codes :: struct {
    	length_slot:    i32,
    	length_code:    i32,
    	distance_code:  i32,
    	distance_extra: i32,
    }

    Deflate_Sequence ¶

    Deflate_Sequence :: struct {
    	distance: i32,
    	length:   i32,
    }

    Deflate_Symbol_Count ¶

    Deflate_Symbol_Count :: struct {
    	items:     i32,
    	literals:  i32,
    	distances: i32,
    }

    Deflate_To_Slice ¶

    Deflate_To_Slice :: proc(s: ^Deflate, output, input: []u8, level: Deflate_Level) -> (written: int, err: compress.Error)

    Matching Procedures (3)

    Gzip_Compression ¶

    Gzip_Compression :: enum u8 {
    	DEFLATE = 8, 
    }

    Gzip_Compression_Flags ¶

    Gzip_Compression_Flags :: enum u8 {
    	Maximum_Compression = 2, 
    	Fastest_Compression = 4, 
    }

    Gzip_Header ¶

    Gzip_Header :: struct #packed {
    	magic:              Gzip_Magic,
    	compression_method: Gzip_Compression,
    	flags:              Gzip_Header_Flags,
    	modification_time:  u32le,
    	xfl:                Gzip_Compression_Flags,
    	os:                 Gzip_OS,
    }

    Gzip_Header_Flag ¶

    Gzip_Header_Flag :: enum u8 {
    	// Order is important
    	text       = 0, 
    	header_crc = 1, 
    	extra      = 2, 
    	name       = 3, 
    	comment    = 4, 
    	reserved_1 = 5, 
    	reserved_2 = 6, 
    	reserved_3 = 7, 
    }

    Gzip_Header_Flags ¶

    Gzip_Header_Flags :: distinct bit_set[Gzip_Header_Flag; u8]

    Gzip_Magic ¶

    Gzip_Magic :: enum u16le {
    	GZIP = 0x8b << 8 | 0x1f, 
    }

    Gzip_OS ¶

    Gzip_OS :: enum u8 {
    	FAT          = 0, 
    	Amiga        = 1, 
    	VMS          = 2, 
    	Unix         = 3, 
    	VM_CMS       = 4, 
    	Atari_TOS    = 5, 
    	HPFS         = 6, 
    	Macintosh    = 7, 
    	Z_System     = 8, 
    	CP_M         = 9, 
    	TOPS_20      = 10, 
    	NTFS         = 11, 
    	QDOS         = 12, 
    	Acorn_RISCOS = 13, 
    	_Unknown     = 14, 
    	Unknown      = 255, 
    }

    Gzip_Trailer ¶

    Gzip_Trailer :: struct #packed {
    	crc32: u32le,
    	size:  u32le,
    }

    Inflate ¶

    Inflate :: struct {
    	input:      []u8,
    	position:   int,
    	bit_buffer: u64,
    	bit_count:  i32,
    	eof:        bool,
    	ctx:        ^compress.Context,
    	literals:   [1334]u32,
    	distances:  [402]u32,
    }

    Inflate_Table_Builder ¶

    Inflate_Table_Builder :: struct {
    	length: i32,
    	count:  i32,
    	word:   i32,
    	sorted: []i16,
    }

    Constants

    DEFLATE_BLOCK_MAX ¶

    DEFLATE_BLOCK_MAX :: DEFLATE_RAW_BLOCK_SIZE

    DEFLATE_COUNT_MAX ¶

    DEFLATE_COUNT_MAX :: ((DEFLATE_LITERAL_SYMBOLS + 3) / 4 + 3) &~ 3

    DEFLATE_DISTANCE_MAX ¶

    DEFLATE_DISTANCE_MAX :: 1 << 15

    DEFLATE_DISTANCE_MAX_CODE_LENGTH ¶

    DEFLATE_DISTANCE_MAX_CODE_LENGTH :: 15

    DEFLATE_HASH3_SIZE ¶

    DEFLATE_HASH3_SIZE :: 1 << DEFLATE_HASH3_BITS

    DEFLATE_HASH_MASK ¶

    DEFLATE_HASH_MASK :: DEFLATE_HASH_SIZE - 1

    DEFLATE_HASH_SIZE ¶

    DEFLATE_HASH_SIZE :: 1 << DEFLATE_HASH_BITS

    DEFLATE_INPUT_MAX ¶

    DEFLATE_INPUT_MAX: int : max(int) - (max(int) >> 8)

    DEFLATE_LEVEL_LAZY ¶

    DEFLATE_LEVEL_LAZY :: Deflate_Level.Level_6

    DEFLATE_LITERAL_MAX_CODE_LENGTH ¶

    DEFLATE_LITERAL_MAX_CODE_LENGTH :: 14

    DEFLATE_MATCH3_DISTANCE ¶

    DEFLATE_MATCH3_DISTANCE :: 4096

    DEFLATE_RAW_BLOCK_SIZE ¶

    DEFLATE_RAW_BLOCK_SIZE :: 65535

    DEFLATE_SEQUENCE_SIZE ¶

    DEFLATE_SEQUENCE_SIZE :: 2 * DEFLATE_BLOCK_MAX / (DEFLATE_MATCH3_MIN + 1) + 3

    DEFLATE_SLIDE_SIZE ¶

    DEFLATE_SLIDE_SIZE :: 1 << 30

    DEFLATE_SYMBOL_BITS ¶

    DEFLATE_SYMBOL_BITS :: u32(10)

    DEFLATE_SYMBOL_MASK ¶

    DEFLATE_SYMBOL_MASK: u32 : (u32(1) << DEFLATE_SYMBOL_BITS) - u32(1)

    DEFLATE_WINDOW_MASK ¶

    DEFLATE_WINDOW_MASK :: DEFLATE_WINDOW_SIZE - 1

    DEFLATE_WINDOW_SIZE ¶

    DEFLATE_WINDOW_SIZE :: DEFLATE_DISTANCE_MAX

    GZIP_MAX_PAYLOAD_SIZE ¶

    GZIP_MAX_PAYLOAD_SIZE :: i64(max(u32le))

    GZIP_OS_NAME ¶

    GZIP_OS_NAME: [Gzip_OS]string : #sparse[Gzip_OS]string{._Unknown = "", .FAT = "FAT", .Amiga = "Amiga", .VMS = "VMS/OpenVMS", .Unix = "Unix", .VM_CMS = "VM/CMS", .Atari_TOS = "Atari TOS", .HPFS = "HPFS", .Macintosh = "Macintosh", .Z_System = "Z-System", .CP_M = "CP/M", .TOPS_20 = "TOPS-20", .NTFS = "NTFS", .QDOS = "QDOS", .Acorn_RISCOS = "Acorn RISCOS", .Unknown = "Unknown"}

    INFLATE_INITIAL_SIZE_MAX ¶

    INFLATE_INITIAL_SIZE_MAX :: 16 * 1024 * 1024

    INFLATE_LITERAL_TABLE_SIZE ¶

    INFLATE_LITERAL_TABLE_SIZE :: 1334

    INFLATE_STREAM_INITIAL_SIZE ¶

    INFLATE_STREAM_INITIAL_SIZE :: 64 * 1024

    SMALL_INPUT_OPTIMIZATION ¶

    SMALL_INPUT_OPTIMIZATION :: #config(SMALL_INPUT_OPTIMIZATION, false)
    -define:SMALL_INPUT_OPTIMIZATION=false
     

    SMALL_INPUT_OPTIMIZATIONS improves compression on inputs smaller than about 1kiB, at the cost of compression speed, especially on Apple silicon, so it's not enabled by default.

    Variables

    DEFLATE_DISTANCE_BASE ¶

    @(rodata)
    DEFLATE_DISTANCE_BASE: [30]i16 = …

    DEFLATE_DISTANCE_EXTRA_BITS ¶

    @(rodata)
    DEFLATE_DISTANCE_EXTRA_BITS: [30]u8 = …

    DEFLATE_DISTANCE_EXTRA_MAX ¶

    @(rodata)
    DEFLATE_DISTANCE_EXTRA_MAX: [14]i16 = …

    DEFLATE_FIXED_DISTANCE_CODE ¶

    @(rodata)
    DEFLATE_FIXED_DISTANCE_CODE: [32]u16 = …

    DEFLATE_FIXED_LITERAL_CODE ¶

    @(rodata)
    DEFLATE_FIXED_LITERAL_CODE: [288]u16 = …

    DEFLATE_FIXED_LITERAL_LENGTH ¶

    @(rodata)
    DEFLATE_FIXED_LITERAL_LENGTH: [288]u8 = …

    DEFLATE_LENGTH_BASE ¶

    @(rodata)
    DEFLATE_LENGTH_BASE: [29]i16 = …

    DEFLATE_LENGTH_EXTRA_BITS ¶

    @(rodata)
    DEFLATE_LENGTH_EXTRA_BITS: [29]u8 = …

    DEFLATE_LENGTH_SLOT ¶

    @(rodata)
    DEFLATE_LENGTH_SLOT: [259]u8 = …

    DEFLATE_LEVEL_NICE ¶

    @(rodata)
    DEFLATE_LEVEL_NICE: [11]u16 = …

    DEFLATE_PRECODE_EXTRA_BITS ¶

    @(rodata)
    DEFLATE_PRECODE_EXTRA_BITS: [19]u8 = …

    DEFLATE_PRECODE_ORDER ¶

    @(rodata)
    DEFLATE_PRECODE_ORDER: [19]u8 = …

    INFLATE_FIXED_DISTANCES ¶

    @(rodata)
    INFLATE_FIXED_DISTANCES: [256]u32 = …

    INFLATE_FIXED_LITERALS ¶

    @(rodata)
    INFLATE_FIXED_LITERALS: [1024]u32 = …

    Procedures

    deflate_bound ¶

    deflate_bound :: proc(len: int) -> int {…}

    deflate_gzip_bound ¶

    deflate_gzip_bound :: proc(len: int) -> int {…}

    deflate_gzip_to_dynamic ¶

    deflate_gzip_to_dynamic :: proc(
    	output:    ^[dynamic]u8, 
    	input:     []u8, 
    	level:     Deflate_Level = Deflate_Level.Default, 
    	allocator := context.allocator, 
    ) -> (err: compress.Error) {…}

    deflate_gzip_to_slice ¶

    deflate_gzip_to_slice :: proc(
    	s:             ^Deflate, 
    	output, input: []u8, 
    	level:         Deflate_Level = Deflate_Level.Default, 
    ) -> (written: int, err: compress.Error) {…}

    deflate_raw_to_dynamic ¶

    deflate_raw_to_dynamic :: proc(
    	output:    ^[dynamic]u8, 
    	input:     []u8, 
    	level:     Deflate_Level = Deflate_Level.Default, 
    	allocator := context.allocator, 
    ) -> (err: compress.Error) {…}

    deflate_raw_to_slice ¶

    deflate_raw_to_slice :: proc(
    	s:             ^Deflate, 
    	output, input: []u8, 
    	level:         Deflate_Level = Deflate_Level.Default, 
    ) -> (written: int, err: compress.Error) {…}

    deflate_zlib_to_dynamic ¶

    deflate_zlib_to_dynamic :: proc(
    	output:    ^[dynamic]u8, 
    	input:     []u8, 
    	level:     Deflate_Level = Deflate_Level.Default, 
    	allocator := context.allocator, 
    ) -> (err: compress.Error) {…}

    deflate_zlib_to_slice ¶

    deflate_zlib_to_slice :: proc(
    	s:             ^Deflate, 
    	output, input: []u8, 
    	level:         Deflate_Level = Deflate_Level.Default, 
    ) -> (written: int, err: compress.Error) {…}

    inflate_gzip_from_bytes ¶

    inflate_gzip_from_bytes :: proc(
    	output:               ^[dynamic]u8, 
    	input:                []u8, 
    	expected_output_size: int = -1, 
    	allocator := context.allocator, 
    ) -> (err: compress.Error) {…}

    inflate_gzip_from_context ¶

    inflate_gzip_from_context :: proc(
    	z:                    ^compress.Context, 
    	expected_output_size: int = -1, 
    	allocator := context.allocator, 
    ) -> (err: compress.Error) {…}

    inflate_raw_from_bytes ¶

    inflate_raw_from_bytes :: proc(
    	output:               ^[dynamic]u8, 
    	input:                []u8, 
    	expected_output_size: int = -1, 
    	allocator := context.allocator, 
    ) -> (err: compress.Error) {…}

    inflate_raw_from_context ¶

    inflate_raw_from_context :: proc(
    	z:                    ^compress.Context, 
    	expected_output_size: int = -1, 
    	allocator := context.allocator, 
    ) -> (err: compress.Error) {…}

    inflate_zlib_from_bytes ¶

    inflate_zlib_from_bytes :: proc(
    	output:               ^[dynamic]u8, 
    	input:                []u8, 
    	expected_output_size: int = -1, 
    	allocator := context.allocator, 
    ) -> (err: compress.Error) {…}

    inflate_zlib_from_context ¶

    inflate_zlib_from_context :: proc(
    	z:                    ^compress.Context, 
    	expected_output_size: int = -1, 
    	allocator := context.allocator, 
    ) -> (err: compress.Error) {…}

    Procedure Groups

    `#config` values

    Source Files

    Generation Information

    Generated with odin version dev-2026-11 (vendor "odin") Windows_amd64 @ 2026-11-03 02:45:12.565449200 +0000 UTC