Iris image format library. Supports encode/decode.
Find a file
2026-01-07 14:22:16 -06:00
codec_test.go Reference implementation of Iris 2026-01-05 11:37:59 -06:00
decode.go Reference implementation of Iris 2026-01-05 11:37:59 -06:00
encode.go Reference implementation of Iris 2026-01-05 11:37:59 -06:00
errors.go Reference implementation of Iris 2026-01-05 11:37:59 -06:00
format.go Reference implementation of Iris 2026-01-05 11:37:59 -06:00
format_test.go Reference implementation of Iris 2026-01-05 11:37:59 -06:00
go.mod Reference implementation of Iris 2026-01-05 11:37:59 -06:00
header.go Reference implementation of Iris 2026-01-05 11:37:59 -06:00
header_test.go Reference implementation of Iris 2026-01-05 11:37:59 -06:00
image.go Reference implementation of Iris 2026-01-05 11:37:59 -06:00
integration_test.go Reference implementation of Iris 2026-01-05 11:37:59 -06:00
iris.go Reference implementation of Iris 2026-01-05 11:37:59 -06:00
license Reference implementation of Iris 2026-01-05 11:37:59 -06:00
lz4.go Reference implementation of Iris 2026-01-05 11:37:59 -06:00
lz4_test.go Reference implementation of Iris 2026-01-05 11:37:59 -06:00
metadata.go Reference implementation of Iris 2026-01-05 11:37:59 -06:00
metadata_test.go Reference implementation of Iris 2026-01-05 11:37:59 -06:00
raw.go Reference implementation of Iris 2026-01-05 11:37:59 -06:00
readme.md Add technical documentation to format 2026-01-07 14:22:16 -06:00
technical.md Add technical documentation to format 2026-01-07 14:22:16 -06:00

Iris Image Format - Go Implementation

A fast, minimal image format optimized for game engines and real-time applications.

Features

  • Simple: Fixed 20-byte header, predictable layout
  • Fast: Custom LZ4 decompression at 2+ GB/s
  • Compact: Better compression than raw, faster than PNG
  • No dependencies: Custom LZ4 implementation, no external packages
  • Flexible: Two APIs - standard image.Image and fast byte-level access

Installation

go get git.sharkk.net/go/iris

Quick Start

Standard API (image.Image compatible)

package main

import (
    "image"
    _ "git.sharkk.net/go/iris" // Register format
    "os"
)

func main() {
    // Decode
    f, _ := os.Open("image.iris")
    img, format, _ := image.Decode(f)
    f.Close()

    // img is now an image.Image
    // format is "iris"
}

Encoding

package main

import (
    "git.sharkk.net/go/iris"
    "os"
)

func main() {
    // Create new image
    img := iris.NewImage(1024, 768, iris.FormatRGBA, iris.BitDepth8)

    // Fill with pixel data...
    // img.Pix() returns []byte for direct access

    // Encode with default options (LZ4 compression)
    f, _ := os.Create("output.iris")
    iris.Encode(f, img)
    f.Close()
}

With Metadata

opts := &iris.EncodeOptions{
    Compression: iris.CompressionLZ4,
    Metadata: iris.Metadata{
        "sdf_range": "4.0",
        "dpi": "96",
        "tool": "myapp/1.0",
    },
}

iris.EncodeWithOptions(f, img, opts)

Fast API (Zero-Copy)

For performance-critical applications like game engines:

// Decode - returns raw pixel bytes
pixels, width, height, format, _ := iris.DecodeFast(reader)

// Upload directly to GPU
gl.TexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height,
    0, gl.RGBA, gl.UNSIGNED_BYTE, pixels)

// Encode
iris.EncodeFast(writer, pixels, width, height,
    iris.FormatRGBA, iris.BitDepth8, iris.CompressionLZ4)

Supported Formats

Format Channels Description
L 1 Grayscale
LA 2 Grayscale + Alpha
RGB 3 Red, Green, Blue
RGBA 4 Red, Green, Blue, Alpha
  • Bit Depth: 8 or 16 bits per channel
  • Compression: Raw (uncompressed) or LZ4
  • Byte Order: Little-endian for 16-bit

Performance

Typical performance on modern hardware:

  • LZ4 Decompression: >1 GB/s
  • LZ4 Compression: >500 MB/s
  • Decode Overhead: <10% vs raw memcpy

Perfect for:

  • SDF textures (smooth distance fields compress well)
  • Game texture assets
  • UI sprites and icons
  • Real-time texture streaming
  • Embedded systems (simple decoder)

API Reference

Core Types

type Image struct {
    // Implements image.Image interface
}

type Format uint8  // L, LA, RGB, RGBA
type Compression uint8  // Raw, LZ4
type BitDepth uint8  // 8, 16

type Metadata map[string]string

Encoding

// Standard encoding with default options (LZ4)
func Encode(w io.Writer, img image.Image) error

// Encoding with custom options
func EncodeWithOptions(w io.Writer, img image.Image, opts *EncodeOptions) error

// Fast byte-level encoding
func EncodeFast(w io.Writer, pixels []byte, width, height int,
                format Format, bitDepth BitDepth, compression Compression) error

Decoding

// Standard decoding (returns image.Image)
func Decode(r io.Reader) (image.Image, error)

// Decode just the config (dimensions, color model)
func DecodeConfig(r io.Reader) (image.Config, error)

// Fast byte-level decoding
func DecodeFast(r io.Reader) (pixels []byte, width, height int,
                               format Format, err error)

Creating Images

// Create new Iris image
func NewImage(width, height int, format Format, bitDepth BitDepth) *Image

// Access methods
img.Pix()          // []byte - raw pixel data
img.Header()       // Header - image properties
img.Metadata()     // Metadata - key-value pairs
img.SetMetadata(key, value)

Metadata Keys

Common metadata keys (from specification):

  • sdf_range - Distance field range for SDF textures (e.g., "4.0")
  • dpi - Dots per inch (e.g., "72", "96")
  • origin - Coordinate origin ("top-left", "bottom-left")
  • created - Creation timestamp
  • tool - Creation tool/version

Unknown keys are preserved for forward compatibility.

Format Details

File Structure

[Header: 20 bytes]
[Metadata: variable, optional]
[Image Data: variable]

Header (20 bytes, little-endian)

Offset Size Field Description
0 4 magic "IRIS" (0x49 0x52 0x49 0x53)
4 1 version Format version (1)
5 1 format Pixel format (0-3)
6 1 compression Compression mode (0-1)
7 1 bit_depth Bits per channel (8 or 16)
8 4 width Image width in pixels
12 4 height Image height in pixels
16 4 meta_size Metadata block size (0 if none)

Pixel Data

  • Raw Mode: Uncompressed pixels in row-major order
  • LZ4 Mode: 4-byte compressed size + LZ4 block data
  • No padding: Pixels are tightly packed
  • 16-bit: Little-endian byte order

Implementation Notes

  • Custom LZ4 implementation (~300 lines, no external dependencies)
  • Safe bounds checking throughout
  • Size limits: 64K pixels per dimension, 1GB uncompressed max
  • Non-premultiplied alpha (NRGBA color model)

Examples

See the spec.md file for the complete format specification and additional examples.

License

This implementation follows the Sharkk Medium License as specified in spec.md.

Key points:

  • Give credit to original authors
  • Share-Alike with same license
  • Non-commercial use only
  • No warranty or liability
  • Source code must be shared

See spec.md for full license text.

Contributing

This is a reference implementation of the Iris specification. See spec.md for format details.