jpegxl

package
v1.0.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 30, 2026 License: MIT Imports: 4 Imported by: 0

Documentation

Index

Constants

View Source
const (
	// ANSLowerBound is the lower bound of state (L) for rANS
	ANSLowerBound = 1 << 16
	// ANSUpperBound is the upper bound for renormalization
	ANSUpperBound = 1 << 24

	// ANSPrecisionBits is the precision for probability representation
	ANSPrecisionBits = 12
	// ANSPrecision is the precision value (4096)
	ANSPrecision = 1 << ANSPrecisionBits
)

ANS constants

View Source
const (
	BlockSize2x2     = 2
	BlockSize4x4     = 4
	BlockSize8x8     = 8
	BlockSize16x16   = 16
	BlockSize32x32   = 32
	BlockSize64x64   = 64
	BlockSize128x128 = 128
	BlockSize256x256 = 256
)

Block sizes supported in JPEG XL VarDCT

Variables

View Source
var (
	ErrInvalidImage      = errors.New("invalid image data")
	ErrUnsupportedMode   = errors.New("unsupported encoding mode")
	ErrInvalidCodestream = errors.New("invalid or truncated codestream")
	ErrANSDecodingFailed = errors.New("ANS decoding failed")
)

Errors

View Source
var ErrInvalidSymbol = errors.New("invalid symbol")

ErrInvalidSymbol indicates an invalid symbol was encountered during ANS decoding.

View Source
var ErrShortInitialState = errors.New("ans: truncated initial state")

ErrShortInitialState indicates the encoded ANS stream is too short to carry an initial rANS state of the required precision (ISO/IEC 18181 §C.3.2).

Functions

func ApplyZigZag

func ApplyZigZag(coeffs []int, size int) []int

ApplyZigZag reorders coefficients in zig-zag order

func ReverseZigZag

func ReverseZigZag(zigzag []int, size int) []int

ReverseZigZag converts from zig-zag to natural order

func ZigZagOrder

func ZigZagOrder(size int) []int

ZigZagOrder returns the zig-zag scan order for given block size

Types

type ANSDecoder

type ANSDecoder struct {
	// contains filtered or unexported fields
}

ANSDecoder implements rANS decoding

func NewANSDecoder

func NewANSDecoder(data []byte, dist *ANSDistribution) *ANSDecoder

NewANSDecoder creates a new rANS decoder

func (*ANSDecoder) DecodeSymbol

func (d *ANSDecoder) DecodeSymbol() (int, error)

DecodeSymbol decodes and returns the next symbol

func (*ANSDecoder) HasMore

func (d *ANSDecoder) HasMore() bool

HasMore returns true if more symbols can be decoded

type ANSDistribution

type ANSDistribution struct {
	// Symbol information
	Symbols []ANSSymbol

	// Number of symbols
	NumSymbols int

	// Alias table for fast decoding
	AliasTable []uint16

	// Total frequency (should sum to ANSPrecision)
	TotalFreq uint32
}

ANSDistribution holds the probability distribution for ANS coding

func NewANSDistribution

func NewANSDistribution(frequencies []uint32) *ANSDistribution

NewANSDistribution creates a distribution from frequency counts

func (*ANSDistribution) GetSymbol

func (d *ANSDistribution) GetSymbol(freqValue uint32) int

GetSymbol returns the symbol for a given frequency value (fast lookup)

type ANSEncoder

type ANSEncoder struct {
	// contains filtered or unexported fields
}

ANSEncoder implements rANS encoding

func NewANSEncoder

func NewANSEncoder(dist *ANSDistribution) *ANSEncoder

NewANSEncoder creates a new rANS encoder

func (*ANSEncoder) EncodeSymbol

func (e *ANSEncoder) EncodeSymbol(symbol int) error

EncodeSymbol encodes a single symbol

func (*ANSEncoder) Finish

func (e *ANSEncoder) Finish() []byte

Finish finalizes encoding and returns the encoded data.

Per ISO/IEC 18181 §C.3.2 the final state is written with a fixed byte count (ansInitialStateBytes) — big-endian after reversal — so that the decoder can read exactly that many bytes when reconstructing the initial state. Padding any unused high bytes with zero is safe because state is bounded by ANSUpperBound.

func (*ANSEncoder) Reset

func (e *ANSEncoder) Reset()

Reset clears the encoder state

type ANSSymbol

type ANSSymbol struct {
	// Cumulative frequency (start of this symbol's range)
	CumulativeFreq uint32

	// Frequency (size of this symbol's range)
	Freq uint32
}

ANSSymbol represents a symbol with its probability distribution

type BlockPartitioner

type BlockPartitioner struct {
	// Minimum block size
	MinBlockSize int

	// Maximum block size
	MaxBlockSize int

	// Quality parameter (affects block size decisions)
	Quality float64
}

BlockPartitioner determines optimal block partitioning

func NewBlockPartitioner

func NewBlockPartitioner(quality float64) *BlockPartitioner

NewBlockPartitioner creates a new block partitioner

func (*BlockPartitioner) Partition

func (p *BlockPartitioner) Partition(data []float64, width, height int) []PartitionInfo

Partition determines the optimal block partitioning for a region

type ClusterConfig

type ClusterConfig struct {
	// Number of clusters
	NumClusters int

	// Cluster assignments (which cluster each context belongs to)
	ClusterMap []int
}

ClusterConfig defines how symbols are clustered for entropy coding

func NewClusterConfig

func NewClusterConfig(numContexts, numClusters int) *ClusterConfig

NewClusterConfig creates a cluster configuration

func (*ClusterConfig) GetCluster

func (cc *ClusterConfig) GetCluster(context int) int

GetCluster returns the cluster for a given context

type ColorSpace

type ColorSpace int

ColorSpace specifies the color space

const (
	ColorSpaceRGB ColorSpace = iota
	ColorSpaceYCbCr
	ColorSpaceGray
)

type ContextModel

type ContextModel struct {
	// Distributions for different contexts
	Distributions []*ANSDistribution

	// Number of contexts
	NumContexts int
	// contains filtered or unexported fields
}

ContextModel manages multiple ANS distributions for context-adaptive coding

func NewContextModel

func NewContextModel(numContexts int) *ContextModel

NewContextModel creates a context model with given number of contexts

func (*ContextModel) GetContext

func (cm *ContextModel) GetContext() int

GetContext computes context index from history

func (*ContextModel) Reset

func (cm *ContextModel) Reset()

Reset clears the context history

func (*ContextModel) UpdateHistory

func (cm *ContextModel) UpdateHistory(symbol int)

UpdateHistory updates the context history

type DCTType

type DCTType int

DCTType represents the type of DCT transform

const (
	DCTType2   DCTType = iota // Standard DCT-II (lossy)
	DCTType4                  // DCT-IV (for Hornuss transform)
	DCTHornuss                // Hornuss 8x8 transform
	DCTAFV                    // AFV (Asymmetric Frequency Value)
)

type Decoder

type Decoder struct {
	Info   *ImageInfo
	Config *EncoderConfig
	// contains filtered or unexported fields
}

Decoder is the JPEG XL decoder

func NewDecoder

func NewDecoder(data []byte) (*Decoder, error)

NewDecoder creates a new JPEG XL decoder

func (*Decoder) Decode

func (d *Decoder) Decode() ([]byte, error)

Decode decodes the image data

func (*Decoder) GetInfo

func (d *Decoder) GetInfo() *ImageInfo

GetInfo returns the image information

type EncodedBlock

type EncodedBlock struct {
	// Block position and size
	X, Y   int
	Width  int
	Height int

	// Quantized coefficients
	QCoeffs []int

	// DC value (for prediction)
	DC int

	// Non-zero count
	NonZeroCount int
}

EncodedBlock represents an encoded DCT block

type EncodedModular

type EncodedModular struct {
	// Encoded residuals per channel
	Residuals [][]int

	// Used contexts
	Contexts [][]int

	// Tree used for encoding
	Tree *MATree
}

EncodedModular represents encoded modular data

type Encoder

type Encoder struct {
	Config *EncoderConfig
	Info   *ImageInfo
	// contains filtered or unexported fields
}

Encoder is the main JPEG XL encoder

func NewEncoder

func NewEncoder(info *ImageInfo, config *EncoderConfig) (*Encoder, error)

NewEncoder creates a new JPEG XL encoder

func (*Encoder) Encode

func (e *Encoder) Encode(data []byte) ([]byte, error)

Encode encodes the image data

type EncoderConfig

type EncoderConfig struct {
	// Encoding mode
	Mode EncodingMode

	// Quality (0-100, 100 = lossless in modular mode)
	Quality float64

	// Use XYB color space (recommended for lossy)
	UseXYB bool

	// Progressive encoding
	Progressive bool

	// Effort level (1-9, higher = smaller file but slower)
	Effort int
}

EncoderConfig holds encoder configuration

func DefaultEncoderConfig

func DefaultEncoderConfig() *EncoderConfig

DefaultEncoderConfig returns default encoder settings

func LosslessEncoderConfig

func LosslessEncoderConfig() *EncoderConfig

LosslessEncoderConfig returns config for lossless encoding

type EncodingMode

type EncodingMode int

EncodingMode specifies the encoding mode

const (
	ModeVarDCT  EncodingMode = iota // Lossy VarDCT mode
	ModeModular                     // Lossless modular mode
	ModeHybrid                      // Combined mode
)

type HybridUintConfig

type HybridUintConfig struct {
	// Split exponent - determines boundary between tokens and raw bits
	SplitExponent int

	// MSB in token - bits stored in the token itself
	MSBInToken int

	// LSB in token - additional low bits in token
	LSBInToken int
}

HybridUintConfig configures hybrid unsigned integer coding

func DefaultHybridUintConfig

func DefaultHybridUintConfig() *HybridUintConfig

DefaultHybridUintConfig returns default hybrid uint configuration

type HybridUintEncoder

type HybridUintEncoder struct {
	Config *HybridUintConfig
	// contains filtered or unexported fields
}

HybridUintEncoder encodes unsigned integers using hybrid method

func NewHybridUintEncoder

func NewHybridUintEncoder(config *HybridUintConfig, tokenDist *ANSDistribution) *HybridUintEncoder

NewHybridUintEncoder creates a new hybrid uint encoder

func (*HybridUintEncoder) EncodeUint

func (e *HybridUintEncoder) EncodeUint(value uint32) error

EncodeUint encodes an unsigned integer

func (*HybridUintEncoder) Finish

func (e *HybridUintEncoder) Finish() (tokens []byte, raw []byte)

Finish returns the encoded data

type ImageInfo

type ImageInfo struct {
	Width       int
	Height      int
	NumChannels int
	BitDepth    int
	ColorSpace  ColorSpace
	HasAlpha    bool
}

ImageInfo describes the input image

type MATree

type MATree struct {
	Nodes []TreeNode
}

MATree is the context tree for modular mode

func DefaultMATree

func DefaultMATree() *MATree

DefaultMATree creates a default prediction tree

func (*MATree) Traverse

func (t *MATree) Traverse(properties map[PropertyID]int) (PredictorType, int)

Traverse walks the tree to find predictor and context for a pixel

type ModularChannel

type ModularChannel struct {
	// Channel dimensions
	Width  int
	Height int

	// Pixel data (int for supporting high bit depths and signed values)
	Data []int

	// Shift amount (for hierarchical coding)
	HShift int
	VShift int
}

ModularChannel represents a single channel in modular mode

func NewModularChannel

func NewModularChannel(width, height int) *ModularChannel

NewModularChannel creates a new modular channel

func (*ModularChannel) GetPixel

func (c *ModularChannel) GetPixel(x, y int) int

GetPixel returns pixel value at (x, y) with boundary handling

func (*ModularChannel) SetPixel

func (c *ModularChannel) SetPixel(x, y, value int)

SetPixel sets pixel value at (x, y)

type ModularEncoder

type ModularEncoder struct {
	// Channels to encode
	Channels []*ModularChannel

	// Prediction tree
	Tree *MATree

	// ANS distributions for each context
	Distributions []*ANSDistribution

	// Number of contexts
	NumContexts int

	// Bit depth
	BitDepth int

	// Weighted predictor (stateful) - ISO/IEC 18181 §H.5.2
	WP *WeightedPredictor
}

ModularEncoder implements JPEG XL modular mode encoding

func NewModularEncoder

func NewModularEncoder(bitDepth int) *ModularEncoder

NewModularEncoder creates a new modular encoder

func (*ModularEncoder) AddChannel

func (e *ModularEncoder) AddChannel(ch *ModularChannel)

AddChannel adds a channel to be encoded

func (*ModularEncoder) Decode

func (e *ModularEncoder) Decode(encoded *EncodedModular) []*ModularChannel

Decode decodes modular data back to channels

func (*ModularEncoder) Encode

func (e *ModularEncoder) Encode() *EncodedModular

Encode encodes all channels using modular mode

func (*ModularEncoder) GetProperties

func (e *ModularEncoder) GetProperties(ch *ModularChannel, chIdx, x, y int) map[PropertyID]int

GetProperties computes property values for a pixel

func (*ModularEncoder) Predict

func (e *ModularEncoder) Predict(ch *ModularChannel, x, y int, predictor PredictorType) int

Predict computes predicted value for pixel at (x, y).

Predict is stateless for every predictor except PredictorWeighted, which maintains per-pixel running state in e.WP. Callers that iterate pixels in raster order (Encode, Decode) must call WP.AdvanceAfterPixel(trueValue) immediately after consuming the returned prediction so the weighted predictor's four sub-predictor errors stay synchronized across encode/decode. For other predictors the call is a no-op.

type PaletteTransform

type PaletteTransform struct {
	// Palette entries
	Palette [][]int // [color][channel]

	// Maximum palette size
	MaxPaletteSize int
}

PaletteTransform converts to palette-based representation

func NewPaletteTransform

func NewPaletteTransform(maxSize int) *PaletteTransform

NewPaletteTransform creates a new palette transform

func (*PaletteTransform) BuildPalette

func (p *PaletteTransform) BuildPalette(channels []*ModularChannel) bool

BuildPalette extracts palette from channels

func (*PaletteTransform) InverseTransform

func (p *PaletteTransform) InverseTransform(indices *ModularChannel, numChannels int) []*ModularChannel

InverseTransform converts palette indices back to channels

func (*PaletteTransform) Transform

func (p *PaletteTransform) Transform(channels []*ModularChannel) *ModularChannel

Transform converts channels to palette indices

type PartitionInfo

type PartitionInfo struct {
	// Block size for this region
	BlockWidth  int
	BlockHeight int

	// Block type
	DCTType DCTType

	// Position
	X, Y int
}

PartitionInfo describes how a region is partitioned

type PredictorType

type PredictorType int

PredictorType represents predictor types available in JPEG XL modular mode

const (
	PredictorZero     PredictorType = iota // Predict zero
	PredictorW                             // Predict W (left)
	PredictorN                             // Predict N (above)
	PredictorAvgWN                         // Average of W and N
	PredictorSelect                        // Select between W and N based on gradient
	PredictorGradient                      // Gradient predictor (W + N - NW, median-of-3 clamp)
	PredictorWeighted                      // ISO/IEC 18181 §H.5.2 self-correcting weighted predictor
	PredictorNE                            // Predict NE (above-right)
	PredictorNW                            // Predict NW (above-left)
	PredictorWW                            // Predict WW (far left)
)

type PropertyID

type PropertyID int

PropertyID identifies a property used for context decisions

const (
	PropChannel PropertyID = iota // Which channel
	PropY                         // Y coordinate
	PropX                         // X coordinate
	PropN                         // Neighbor pixel N (above)
	PropW                         // Neighbor pixel W (left)
	PropNE                        // Neighbor pixel NE
	PropNW                        // Neighbor pixel NW
	PropWW                        // Neighbor pixel WW
	PropNN                        // Neighbor pixel NN
	PropGradN                     // Gradient N-NN
	PropGradW                     // Gradient W-WW
	PropGradNW                    // Gradient NW corner
)

type QuantMatrix

type QuantMatrix struct {
	// Quantization steps per frequency
	Steps []float64

	// Block size
	Size int

	// Base quality step
	BaseStep float64
}

QuantMatrix represents a quantization matrix

func NewQuantMatrix

func NewQuantMatrix(size int, quality float64) *QuantMatrix

NewQuantMatrix creates a quantization matrix for given size and quality

func (*QuantMatrix) Dequantize

func (qm *QuantMatrix) Dequantize(qcoeffs []int) []float64

Dequantize reverses quantization

func (*QuantMatrix) Quantize

func (qm *QuantMatrix) Quantize(coeffs []float64) []int

Quantize applies quantization to coefficients

type SqueezeTransform

type SqueezeTransform struct{}

SqueezeTransform implements the squeeze (Haar-like) transform.

ISO/IEC 18181 §H.4.1.1 specifies floor-division arithmetic (arithmetic right shift on signed integers). Go's `/2` truncates toward zero, which rounds negative residuals the wrong way. Using `>>1` gives the spec's floor semantics for signed ints and keeps Forward∘Inverse an identity on mixed-sign channels.

func (*SqueezeTransform) Forward

Forward applies forward squeeze transform

func (*SqueezeTransform) Inverse

func (s *SqueezeTransform) Inverse(avg, res *ModularChannel) *ModularChannel

Inverse applies inverse squeeze transform.

Identity: given avg = (a+b) >> 1 and res = a - b, recovering (a, b) from (avg, res) must work for mixed-sign inputs. We use:

b = avg - (res >> 1)
a = b + res

which holds for all integer a, b, because arithmetic right shift matches floor division: avg = floor((a+b)/2) = ((a+b) - ((a+b)&1)) / 2 and (a+b)&1 == res&1 == (a-b)&1, so b = avg - (res>>1) inverts exactly.

type TreeNode

type TreeNode struct {
	Type TreeNodeType

	// For property nodes
	Property   PropertyID
	SplitVal   int
	LeftChild  int // Index of left child (if <= SplitVal)
	RightChild int // Index of right child (if > SplitVal)

	// For leaf nodes
	Predictor  PredictorType
	Context    int
	Multiplier int
}

TreeNode represents a node in the prediction/context tree

type TreeNodeType

type TreeNodeType int

TreeNodeType represents types of nodes in the decision tree

const (
	TreeNodeLeaf     TreeNodeType = iota // Leaf node (predictor selection)
	TreeNodeProperty                     // Property-based split
)

type VarDCTBlock

type VarDCTBlock struct {
	// Block dimensions
	Width  int
	Height int

	// DCT type
	Type DCTType

	// Coefficients (in zig-zag order)
	Coefficients []float64

	// Position in image
	X, Y int
}

VarDCTBlock represents a variable-size DCT block

type VarDCTEncoder

type VarDCTEncoder struct {
	// Transform
	Transform *VarDCTTransform

	// Block partitioner
	Partitioner *BlockPartitioner

	// Quantization matrices by block size
	QuantMatrices map[int]*QuantMatrix

	// Quality setting
	Quality float64
}

VarDCTEncoder combines transform, quantization, and entropy coding

func NewVarDCTEncoder

func NewVarDCTEncoder(quality float64) *VarDCTEncoder

NewVarDCTEncoder creates a new VarDCT encoder

func (*VarDCTEncoder) DecodeRegion

func (e *VarDCTEncoder) DecodeRegion(blocks []EncodedBlock, width, height int) []float64

DecodeRegion decodes VarDCT blocks back to pixels

func (*VarDCTEncoder) EncodeRegion

func (e *VarDCTEncoder) EncodeRegion(data []float64, width, height int) []EncodedBlock

EncodeRegion encodes a region using VarDCT

type VarDCTTransform

type VarDCTTransform struct {
	// contains filtered or unexported fields
}

VarDCTTransform implements variable-size DCT for JPEG XL

func NewVarDCTTransform

func NewVarDCTTransform() *VarDCTTransform

NewVarDCTTransform creates a new VarDCT transformer

func (*VarDCTTransform) Forward2D

func (t *VarDCTTransform) Forward2D(block []float64, width, height int) []float64

Forward2D applies 2D DCT to a block

func (*VarDCTTransform) Inverse2D

func (t *VarDCTTransform) Inverse2D(coeffs []float64, width, height int) []float64

Inverse2D applies inverse 2D DCT to a block

type WeightedPredictor

type WeightedPredictor struct {
	// contains filtered or unexported fields
}

WeightedPredictor holds the rolling per-row state required by §H.5.2.

For each sub-predictor k in {0..3} we maintain an absolute-error buffer err[k] of length 2*width (one slot per pixel in the current and previous rows). trueErr stores signed prediction errors for sub-predictor 0 (the only one libjxl feeds back into the next prediction). weights is the fixed weight vector.

func NewWeightedPredictor

func NewWeightedPredictor() *WeightedPredictor

NewWeightedPredictor constructs a predictor with libjxl's default weight vector. Width-dependent buffers are allocated lazily by Reset.

func (*WeightedPredictor) AdvanceAfterPixel

func (wp *WeightedPredictor) AdvanceAfterPixel(x, y, width, trueVal, pred int)

AdvanceAfterPixel updates the running error state with the now-known true pixel value, computing the per-sub-predictor residuals and storing them in the rolling buffers.

func (*WeightedPredictor) Predict

func (wp *WeightedPredictor) Predict(x, y, width int, nb wpNeighbors) int

Predict returns the weighted prediction for pixel (x, y).

The caller must then invoke AdvanceAfterPixel (or SkipPixel if the weighted predictor was not selected for this pixel) so the running error state stays aligned with the pixel stream.

func (*WeightedPredictor) Reset

func (wp *WeightedPredictor) Reset(width int)

Reset prepares the predictor for a new channel of the given width. Buffers are resized / zeroed so predictions on the first pixel of a channel start from a clean state.

func (*WeightedPredictor) SkipPixel

func (wp *WeightedPredictor) SkipPixel(x, y, width int)

SkipPixel advances the rolling buffers by one position without updating any error terms. This keeps the (row-indexed) buffers coherent when a non-weighted predictor was selected for this pixel but a later pixel in the same channel will use the weighted predictor.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL