Skip to content

Pure Go JPEG 2000 codec with HTJ2K support (ISO/IEC 15444-1, 15444-15)

License

Notifications You must be signed in to change notification settings

mrjoshuak/go-jpeg2000

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

25 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

go-jpeg2000

Go Reference Go Report Card License

A pure Go implementation of the JPEG 2000 image codec (ISO/IEC 15444-1) with HTJ2K support (ISO/IEC 15444-15).

Overview

This package provides a native Go implementation of JPEG 2000 encoding and decoding, aiming for 100% parity with the OpenJPEG reference implementation. It supports both lossless (5-3 reversible wavelet) and lossy (9-7 irreversible wavelet) compression.

Features

  • Pure Go: No CGO dependencies, works on all Go-supported platforms
  • Format Support: JP2 file format and raw J2K codestream
  • HTJ2K Support: High-Throughput JPEG 2000 (ISO/IEC 15444-15) with full cleanup + refinement passes (SPP/MRP)
  • Progressive Decode: Incremental decoding via ProgressiveDecoder β€” feed packets as they arrive, reconstruct at any point
  • Float Image Output: FloatImage type preserves HDR float precision through the decode pipeline
  • Packet Extraction: ExtractPackets / BuildPacketIndex for server-side progressive streaming
  • Lossless & Lossy: Both compression modes supported
  • Full Colorspace Support: All 19 ISO/IEC 15444-1 colorspaces with automatic conversion to sRGB
  • 32-bit Float Encoding: EncodeFloat preserves IEEE 754 float32 values via NLT Type 3 markers (bitwise lossless)
  • Flexible Precision: 1-32 bit component precision, including 4-bit, 10-bit, 12-bit, and 32-bit float
  • Standard Library Integration: Implements image.Image interface
  • Auto-registration: Registers with Go's image package for transparent decode

Installation

go get github.com/mrjoshuak/go-jpeg2000

Usage

Decoding

package main

import (
    "image"
    "os"

    _ "github.com/mrjoshuak/go-jpeg2000" // Register format
)

func main() {
    file, _ := os.Open("image.jp2")
    defer file.Close()

    img, format, err := image.Decode(file)
    if err != nil {
        panic(err)
    }
    // Use img...
}

Encoding

package main

import (
    "image"
    "os"

    "github.com/mrjoshuak/go-jpeg2000"
)

func main() {
    // Load or create an image
    img := createImage()

    file, _ := os.Create("output.jp2")
    defer file.Close()

    opts := jpeg2000.DefaultOptions()
    opts.Lossless = true

    err := jpeg2000.Encode(file, img, opts)
    if err != nil {
        panic(err)
    }
}

Reading Metadata

file, _ := os.Open("image.jp2")
meta, err := jpeg2000.DecodeMetadata(file)
if err != nil {
    panic(err)
}

fmt.Printf("Size: %dx%d\n", meta.Width, meta.Height)
fmt.Printf("Components: %d\n", meta.NumComponents)
fmt.Printf("ColorSpace: %v\n", meta.ColorSpace)
fmt.Printf("Tiles: %dx%d\n", meta.NumTilesX, meta.NumTilesY)

Float Encoding (32-bit HDR)

// Encode float32 data with bitwise-lossless preservation
floatImg := &jpeg2000.FloatImage{
    Width:      width,
    Height:     height,
    Components: [][]float32{rChannel, gChannel, bChannel},
    BitDepth:   32,
    Signed:     true,
}

opts := jpeg2000.DefaultOptions()
opts.Format = jpeg2000.FormatJ2K

err := jpeg2000.EncodeFloat(file, floatImg, opts)

Float encoding uses NLT Type 3 markers to reinterpret IEEE 754 float32 bits as int32 with a sign-magnitude transform, preserving all values including NaN, Inf, and -0.0.

Float Decoding (HDR)

// Preserve float precision through the decode pipeline
floatImg, err := jpeg2000.DecodeFloat(file)
// floatImg.Components[0] is []float32 for the first component (e.g. R)
// floatImg.Components[1] is []float32 for G, etc.

// With config options
cfg := &jpeg2000.Config{ReduceResolution: 2}
floatImg, err = jpeg2000.DecodeFloatConfig(file, cfg)

Progressive Decoding

// Parse the codestream header, then feed packets incrementally
decoder, err := jpeg2000.NewProgressiveDecoderFromCodestream(codestreamBytes)

// Feed packets as they arrive (any order)
for _, pkt := range packets {
    decoder.FeedPacket(pkt)
}

// Reconstruct the best image from data received so far
floatImg, err := decoder.Reconstruct()

// Check progress
fmt.Printf("Received %d packets, complete: %v\n",
    len(decoder.ReceivedPackets()), decoder.Complete())

Packet Extraction (Server-Side)

// Extract all packets from an encoded codestream
packets, err := jpeg2000.ExtractPackets(codestream)

// Or build a zero-copy index for memory-mapped files
index, err := jpeg2000.BuildPacketIndex(codestream)
pkt, err := index.GetPacket(addr)
addrs := index.AllAddresses()

Encoding Options

opts := &jpeg2000.Options{
    Format:           jpeg2000.FormatJP2,      // or FormatJ2K, FormatJPX
    Lossless:         true,                     // Use 5-3 reversible wavelet
    Quality:          75,                       // 1-100, for lossy mode
    CompressionRatio: 20,                       // Alternative to Quality (20:1)
    NumResolutions:   6,                        // Decomposition levels + 1
    NumLayers:        1,                        // Quality layers
    ProgressionOrder: jpeg2000.LRCP,           // Packet ordering
    CodeBlockSize:    image.Point{6, 6},       // 64x64 code blocks
    TileSize:         image.Point{512, 512},   // Tile dimensions
    ColorSpace:       jpeg2000.ColorSpaceSRGB, // Output colorspace
    Precision:        12,                       // Override bit depth (1-16)
    EnableSOP:        true,                     // Start of packet markers
    EnableEPH:        true,                     // End of packet header markers
    Comment:          "Created with go-jpeg2000",
}

Colorspace Support

Full support for all colorspaces defined in ISO/IEC 15444-1 Annex M:

enumcs Colorspace API Constant Description
0 Bi-level ColorSpaceBilevel Black and white
1 YCbCr(1) ColorSpaceSYCC ITU-R BT.709-5 (sRGB primaries)
3 YCbCr(2) ColorSpaceYCbCr2 ITU-R BT.601-5 (625-line PAL/SECAM)
4 YCbCr(3) ColorSpaceYCbCr3 ITU-R BT.601-5 (525-line NTSC)
9 PhotoYCC ColorSpacePhotoYCC Kodak Photo CD
11 CMY ColorSpaceCMY Cyan, Magenta, Yellow
12 CMYK ColorSpaceCMYK CMY + Key (Black)
13 YCCK ColorSpaceYCCK PhotoYCC + Key
14 CIELab ColorSpaceCIELab CIE L*a*b* (D50)
15 Bi-level(2) ColorSpaceBilevel Alternative bi-level
16 sRGB ColorSpaceSRGB Standard RGB (IEC 61966-2-1)
17 Grayscale ColorSpaceGray Single component gray
18 sYCC ColorSpaceSYCC sRGB-based YCbCr
19 CIEJab ColorSpaceCIEJab CIECAM02 J*a*b*
20 e-sRGB ColorSpaceESRGB Extended gamut sRGB
21 ROMM-RGB ColorSpaceROMMRGB ProPhoto RGB (ISO 22028-2)
22 YPbPr(60) ColorSpaceYPbPr60 HD video 1125/60 (SMPTE 274M)
23 YPbPr(50) ColorSpaceYPbPr50 HD video 1250/50 (ITU-R BT.1361)
24 e-sYCC ColorSpaceEYCC Extended gamut sYCC

Colorspace Handling

  • Automatic Conversion: All colorspaces are automatically converted to sRGB during decode
  • OpenJPEG Compatible: API values 0-5 match OpenJPEG's OPJ_COLOR_SPACE enum
  • Unspecified vs Unknown:
    • ColorSpaceUnspecified (0): Returned for raw J2K codestreams without JP2 container
    • ColorSpaceUnknown (-1): Returned for unrecognized enumcs values

Color Conversion Details

The decoder applies mathematically correct color transformations based on the specifications:

Colorspace Conversion Method
YCbCr variants ITU-R BT.601/709 matrix inversion
CMY/CMYK Subtractive color model
CIELab Lab→XYZ→sRGB with D50→D65 adaptation
CIEJab CIECAM02 inverse (simplified)
ROMM-RGB Wide gamut to sRGB with clipping
PhotoYCC Kodak-specific YCC matrix

JPEG 2000 Profiles

Supported profiles (RSIZ parameter):

Profile Constant Description
None ProfileNone No restrictions
Cinema 2K ProfileCinema2K 2K Digital Cinema
Cinema 4K ProfileCinema4K 4K Digital Cinema
Cinema S2K ProfileCinemaS2K 2K Scalable Cinema
Cinema S4K ProfileCinemaS4K 4K Scalable Cinema
Cinema SLTE ProfileCinemaSLTE Long-term extension
Broadcast Single ProfileBroadcastSingle Single-tile broadcast
Broadcast Multi ProfileBroadcastMulti Multi-tile broadcast
IMF 2K/4K/8K ProfileIMF2K/4K/8K Interoperable Master Format

Progression Orders

Order Constant Description
LRCP LRCP Layer-Resolution-Component-Position
RLCP RLCP Resolution-Layer-Component-Position
RPCL RPCL Resolution-Position-Component-Layer
PCRL PCRL Position-Component-Resolution-Layer
CPRL CPRL Component-Position-Resolution-Layer

Architecture

jpeg2000/
β”œβ”€β”€ jpeg2000.go          # Public API, types, image registration
β”œβ”€β”€ decoder.go           # JP2/J2K decoding, colorspace detection
β”œβ”€β”€ encoder.go           # JP2/J2K encoding (integer + float32)
β”œβ”€β”€ nlt.go               # Non-Linearity Transform (NLT Type 3 for float)
β”œβ”€β”€ colorspace.go        # Color conversion functions
β”œβ”€β”€ floatimage.go        # FloatImage type for HDR output
β”œβ”€β”€ progressive.go       # ProgressiveDecoder for incremental decode
β”œβ”€β”€ packets.go           # Packet extraction and indexing
└── internal/
    β”œβ”€β”€ bio/             # Bit I/O utilities
    β”œβ”€β”€ box/             # JP2 file format box handling
    β”œβ”€β”€ codestream/      # J2K codestream marker parsing
    β”œβ”€β”€ dwt/             # Discrete Wavelet Transform (5-3, 9-7)
    β”œβ”€β”€ entropy/         # MQ coder, EBCOT tier-1, HTJ2K (cleanup + SPP/MRP)
    β”œβ”€β”€ mct/             # Multi-Component Transform (RCT, ICT)
    └── tcd/             # Tile Coder/Decoder, tier-2

Implementation Status

Component Status Coverage Notes
JP2 Box Parsing βœ… Complete 99.3% All standard box types
Codestream Parsing βœ… Complete 91.0% All main/tile-part markers
5-3 DWT (Lossless) βœ… Complete 100% Reversible wavelet
9-7 DWT (Lossy) βœ… Complete 100% Irreversible wavelet
MCT (Color Transform) βœ… Complete 100% RCT and ICT
MQ Coder βœ… Complete 95.7% Arithmetic coding
HTJ2K (Part 15) βœ… Complete 90%+ Cleanup + SPP/MRP refinement passes
EBCOT (Tier-1) βœ… Complete 91.9% All coding passes
Packet Assembly (Tier-2) βœ… Complete 91.9% All progression orders
Colorspace Conversion βœ… Complete 92.8% All 19 colorspaces
Encoder βœ… Complete 92.8% All image types
Decoder βœ… Complete 92.8% Full colorspace support

Overall Test Coverage: 91-100% across all packages

Supported Image Types

Decoding Output

  • image.Gray / image.Gray16 - Grayscale
  • image.RGBA / image.RGBA64 - RGB with alpha
  • image.NRGBA / image.NRGBA64 - Non-premultiplied RGBA
  • jpeg2000.FloatImage - Planar float32 components (via DecodeFloat)

Encoding Input

  • image.Gray / image.Gray16
  • image.RGBA / image.RGBA64
  • image.NRGBA / image.NRGBA64
  • image.YCbCr
  • image.Paletted
  • jpeg2000.FloatImage - Planar float32 components (via EncodeFloat)

Testing

# Run all tests
go test ./...

# Run with coverage
go test -cover ./...

# Run with race detection
go test -race ./...

# Run benchmarks
go test -bench=. ./...

# Verbose output
go test -v ./...

Performance

The implementation prioritizes correctness and Go idioms over raw performance. For performance-critical applications, consider:

  • Using appropriate tile sizes for your workload
  • Reducing resolution levels for preview generation
  • Using lossless mode only when necessary

Conformance

This implementation aims to conform to:

  • ISO/IEC 15444-1:2019 - JPEG 2000 Part 1 (Core)
  • ISO/IEC 15444-15:2019 - JPEG 2000 Part 15 (HTJ2K)
  • ITU-T Rec. T.800 - Equivalent ITU specification
  • OpenJPEG behavior - API compatibility where applicable

Known Limitations

  • Part 2 (JPX) extensions are not fully supported
  • Some advanced features (ROI, progression order changes mid-stream) are limited

Standards Compliance

This library implements the JPEG 2000 standards as defined by ISO/IEC 15444. The OpenJPEG project serves as the official ISO/IEC reference implementation and was consulted for clarification of standard behavior.

Contributing

Contributions are welcome! Please ensure:

  • All tests pass (go test ./...)
  • Code coverage remains above 90%
  • New features include tests
  • Documentation is updated

License

Apache License 2.0. See LICENSE file for details.

References

About

Pure Go JPEG 2000 codec with HTJ2K support (ISO/IEC 15444-1, 15444-15)

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Packages