mj2

package
v1.0.0 Latest Latest
Warning

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

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

Documentation

Overview

Package mj2 implements Motion JPEG 2000 (MJ2/MJP2) per ISO/IEC 15444-3.

Overview

Motion JPEG 2000 is a video format that uses JPEG 2000 for intra-frame compression within an ISO base media file format (ISOBMFF) container. Unlike most video codecs, MJ2 uses only intra-frame (I-frame) coding, meaning each frame is a complete, independently decodable JP2 codestream.

File Structure

An MJ2 file consists of a sequence of boxes (atoms) following the ISOBMFF standard:

ftyp  - File Type Box (required, must be first)
moov  - Movie Box (required, contains metadata)
  mvhd  - Movie Header Box
  trak  - Track Box (one per track)
    tkhd  - Track Header Box
    mdia  - Media Box
      mdhd  - Media Header Box
      hdlr  - Handler Reference Box
      minf  - Media Information Box
        stbl  - Sample Table Box
          stsd  - Sample Description (mjp2 entries)
          stts  - Time-to-Sample
          stsc  - Sample-to-Chunk
          stsz  - Sample Size
          stco  - Chunk Offset (32-bit)
          stss  - Sync Sample (optional)
mdat  - Media Data Box (contains frame data)

Key Features

  • Each video frame is an independent JP2 codestream
  • No inter-frame dependencies (all frames are sync samples)
  • Random access to any frame without decoding other frames
  • Supports multiple video and audio tracks
  • Full timing and synchronization information

Usage

Basic usage to extract and decode video frames:

// Create reader
reader := mj2.NewReader(data)

// Parse file structure
if err := reader.Parse(); err != nil {
    return err
}

// Get movie information
movie := reader.GetMovie()
fmt.Printf("Duration: %.2f seconds\n", movie.Duration())
fmt.Printf("Tracks: %d\n", len(movie.Tracks))

// Extract frames from first video track
for i := 0; i < movie.Tracks[0].FrameCount(); i++ {
    frame, err := reader.ExtractFrame(0, i)
    if err != nil {
        continue
    }
    // frame is a raw JP2 codestream that can be decoded
    // using the jpeg2000.Decoder
}

Security Considerations

This package validates all input data and enforces security limits:

  • Maximum box sizes are validated to prevent resource exhaustion
  • Integer conversions use safe conversion utilities
  • All array indices are bounds-checked
  • Nested box depth is limited to prevent stack overflow

References

  • ISO/IEC 15444-3: Motion JPEG 2000
  • ISO/IEC 14496-12: ISO base media file format

Package mj2 provides Motion JPEG 2000 (MJ2/MJP2) decoding support per ISO/IEC 15444-3.

Package mj2 provides Motion JPEG 2000 (MJ2/MJP2) decoding support per ISO/IEC 15444-3.

MJ2 is a video format that uses JPEG 2000 for frame compression within an ISO base media file format (ISOBMFF) container. Each video frame is an independent JP2 codestream that can be decoded without reference to other frames.

Key features:

  • ISO base media file format container (similar to MP4)
  • Each frame is a complete JP2 codestream
  • All frames are intra-coded (no inter-frame prediction)
  • Supports multiple video tracks
  • Full timing and synchronization information

Index

Constants

View Source
const (
	// File structure boxes
	BoxTypeFtyp = 0x66747970 // 'ftyp' - File Type Box
	BoxTypeMoov = 0x6D6F6F76 // 'moov' - Movie Box
	BoxTypeMdat = 0x6D646174 // 'mdat' - Media Data Box
	BoxTypeFree = 0x66726565 // 'free' - Free Space Box
	BoxTypeSkip = 0x736B6970 // 'skip' - Skip Box

	// Movie boxes
	BoxTypeMvhd = 0x6D766864 // 'mvhd' - Movie Header Box
	BoxTypeTrak = 0x7472616B // 'trak' - Track Box
	BoxTypeUdta = 0x75647461 // 'udta' - User Data Box

	// Track boxes
	BoxTypeTkhd = 0x746B6864 // 'tkhd' - Track Header Box
	BoxTypeMdia = 0x6D646961 // 'mdia' - Media Box
	BoxTypeTref = 0x74726566 // 'tref' - Track Reference Box
	BoxTypeEdts = 0x65647473 // 'edts' - Edit Box

	// Media boxes
	BoxTypeMdhd = 0x6D646864 // 'mdhd' - Media Header Box
	BoxTypeHdlr = 0x68646C72 // 'hdlr' - Handler Reference Box
	BoxTypeMinf = 0x6D696E66 // 'minf' - Media Information Box

	// Media information boxes
	BoxTypeVmhd = 0x766D6864 // 'vmhd' - Video Media Header Box
	BoxTypeDinf = 0x64696E66 // 'dinf' - Data Information Box
	BoxTypeStbl = 0x7374626C // 'stbl' - Sample Table Box

	// Data information boxes
	BoxTypeDref = 0x64726566 // 'dref' - Data Reference Box
	BoxTypeUrl  = 0x75726C20 // 'url ' - Data Entry URL Box

	// Sample table boxes
	BoxTypeStsd = 0x73747364 // 'stsd' - Sample Description Box
	BoxTypeStts = 0x73747473 // 'stts' - Time-to-Sample Box
	BoxTypeStsc = 0x73747363 // 'stsc' - Sample-to-Chunk Box
	BoxTypeStsz = 0x7374737A // 'stsz' - Sample Size Box
	BoxTypeStco = 0x7374636F // 'stco' - Chunk Offset Box (32-bit)
	BoxTypeCo64 = 0x636F3634 // 'co64' - Chunk Offset Box (64-bit)
	BoxTypeStss = 0x73747373 // 'stss' - Sync Sample Box

	// MJ2-specific boxes
	BoxTypeMjp2 = 0x6D6A7032 // 'mjp2' - Motion JPEG 2000 Sample Entry
	BoxTypeJp2h = 0x6A703268 // 'jp2h' - JP2 Header Box
	BoxTypeIhdr = 0x69686472 // 'ihdr' - Image Header Box
	BoxTypeColr = 0x636F6C72 // 'colr' - Color Specification Box
)

ISO Base Media File Format box types

View Source
const (
	HandlerTypeVideo = "vide" // Video handler
	HandlerTypeAudio = "soun" // Sound handler
	HandlerTypeHint  = "hint" // Hint handler
)

Handler types

Variables

View Source
var (
	BrandMjp2 = [4]byte{'m', 'j', 'p', '2'} // Motion JPEG 2000 brand
	BrandJp2  = [4]byte{'j', 'p', '2', ' '} // JPEG 2000 brand
)

MJ2 file type brands

View Source
var (
	ErrInvalidMJ2File     = errors.New("invalid MJ2 file")
	ErrMissingFtyp        = errors.New("missing ftyp box")
	ErrMissingMoov        = errors.New("missing moov box")
	ErrInvalidBox         = errors.New("invalid box structure")
	ErrTruncatedData      = errors.New("truncated data")
	ErrNoVideoTrack       = errors.New("no video track found")
	ErrFrameOutOfBounds   = errors.New("frame index out of bounds")
	ErrTrackOutOfBounds   = errors.New("track index out of bounds")
	ErrInvalidSampleTable = errors.New("invalid sample table")
	ErrMissingMdat        = errors.New("missing mdat box")
	ErrUnsupportedBrand   = errors.New("unsupported file brand")
)

Errors for MJ2 parsing

Functions

This section is empty.

Types

type Box

type Box struct {
	Type     uint32
	Size     uint64 // Total box size including header
	Data     []byte
	Children []*Box // For container boxes
	Offset   int64  // Position in file
}

Box represents a generic ISO base media file format box.

func (*Box) TypeString

func (b *Box) TypeString() string

TypeString returns the box type as a 4-character string.

type FrameInfo

type FrameInfo struct {
	Index        int
	Offset       uint64
	Size         uint32
	Timestamp    float64 // In seconds
	Duration     float64 // In seconds
	IsSyncSample bool
}

FrameInfo contains information about a single video frame.

type HandlerReference

type HandlerReference struct {
	HandlerType string
	Name        string
}

HandlerReference contains the handler reference box (hdlr) data.

type JP2Header

type JP2Header struct {
	Width       uint32
	Height      uint32
	NumComps    uint16
	BitsPerComp uint8
	Signed      bool
	ColorSpace  int
}

JP2Header contains the JP2 header information embedded in mjp2 sample entry.

type Media

type Media struct {
	Header  *MediaHeader
	Handler *HandlerReference
}

Media contains the media box (mdia) data.

type MediaHeader

type MediaHeader struct {
	Version          uint8
	CreationTime     uint64
	ModificationTime uint64
	Timescale        uint32
	Duration         uint64
	Language         uint16
}

MediaHeader contains the media header box (mdhd) data.

type Movie

type Movie struct {
	Header    *MovieHeader
	Tracks    []*Track
	Timescale uint32 // Movie timescale (from mvhd)
	DurationV uint64 // Duration in movie timescale units
}

Movie represents the parsed movie structure (moov box contents).

func (*Movie) Duration

func (m *Movie) Duration() float64

Duration returns the movie duration in seconds.

type MovieHeader

type MovieHeader struct {
	Version          uint8
	CreationTime     uint64
	ModificationTime uint64
	Timescale        uint32
	Duration         uint64
	Rate             uint32 // 16.16 fixed point
	Volume           uint16 // 8.8 fixed point
	Matrix           [9]uint32
	NextTrackID      uint32
}

MovieHeader contains the movie header box (mvhd) data.

type Reader

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

Reader parses MJ2 (Motion JPEG 2000) files.

func NewReader

func NewReader(data []byte) *Reader

NewReader creates a new MJ2 reader.

func (*Reader) ExtractFrame

func (r *Reader) ExtractFrame(trackIdx, frameIdx int) ([]byte, error)

ExtractFrame extracts a video frame as raw JP2 codestream data.

func (*Reader) GetFrameInfo

func (r *Reader) GetFrameInfo(trackIdx, frameIdx int) (*FrameInfo, error)

GetFrameInfo returns information about a specific frame.

func (*Reader) GetMovie

func (r *Reader) GetMovie() *Movie

GetMovie returns the parsed movie structure.

func (*Reader) GetVideoTracks

func (r *Reader) GetVideoTracks() []*Track

GetVideoTracks returns all video tracks in the movie.

func (*Reader) IsFrameIndependent

func (r *Reader) IsFrameIndependent(trackIdx, frameIdx int) bool

IsFrameIndependent returns true if the frame can be decoded independently. For MJ2, all frames are independent (intra-coded).

func (*Reader) Parse

func (r *Reader) Parse() error

Parse parses the MJ2 file structure.

type SampleDescription

type SampleDescription struct {
	Entries []*SampleEntry
}

SampleDescription contains sample description (stsd) data.

type SampleEntry

type SampleEntry struct {
	Type            uint32
	DataRefIndex    uint16
	Width           uint16
	Height          uint16
	HorizResolution uint32 // 16.16 fixed point (DPI)
	VertResolution  uint32 // 16.16 fixed point (DPI)
	FrameCount      uint16
	CompressorName  string
	Depth           uint16
	JP2Header       *JP2Header // For mjp2 entries
}

SampleEntry represents a sample entry in stsd.

type SampleTable

type SampleTable struct {
	Description   *SampleDescription
	TimeToSample  []TimeToSampleEntry
	SampleToChunk []SampleToChunkEntry
	SampleSizes   []uint32 // Individual sample sizes (if not uniform)
	UniformSize   uint32   // Uniform sample size (0 if variable)
	SampleCount   int
	ChunkOffsets  []uint64 // 32 or 64-bit chunk offsets
	SyncSamples   []uint32 // List of sync (keyframe) sample numbers
}

SampleTable contains the sample table (stbl) data.

func (*SampleTable) GetSampleOffset

func (st *SampleTable) GetSampleOffset(index int) uint64

GetSampleOffset returns the byte offset of sample at index (0-based).

func (*SampleTable) GetSampleSize

func (st *SampleTable) GetSampleSize(index int) uint32

GetSampleSize returns the size of sample at index (0-based).

func (*SampleTable) IsSyncSample

func (st *SampleTable) IsSyncSample(index int) bool

IsSyncSample returns true if the sample at index is a sync sample (keyframe).

type SampleToChunkEntry

type SampleToChunkEntry struct {
	FirstChunk           uint32 // First chunk number (1-based)
	SamplesPerChunk      uint32 // Samples in each chunk
	SampleDescriptionIdx uint32 // Sample description index
}

SampleToChunkEntry represents an entry in the sample-to-chunk (stsc) table.

type TimeToSampleEntry

type TimeToSampleEntry struct {
	SampleCount uint32 // Number of consecutive samples with this delta
	SampleDelta uint32 // Duration of each sample in timescale units
}

TimeToSampleEntry represents an entry in the time-to-sample (stts) table.

type Track

type Track struct {
	Header      *TrackHeader
	Media       *Media
	ID          uint32
	TrackType   string // "vide", "soun", etc.
	SampleTable *SampleTable
}

Track represents a single track in the movie.

func (*Track) DurationSeconds

func (t *Track) DurationSeconds() float64

DurationSeconds returns the track duration in seconds.

func (*Track) FrameCount

func (t *Track) FrameCount() int

FrameCount returns the number of frames/samples in this track.

func (*Track) FrameRate

func (t *Track) FrameRate() float64

FrameRate returns the frame rate for video tracks.

type TrackHeader

type TrackHeader struct {
	Version          uint8
	Flags            uint32
	CreationTime     uint64
	ModificationTime uint64
	TrackID          uint32
	Duration         uint64
	Layer            int16
	AlternateGroup   int16
	Volume           int16 // 8.8 fixed point
	Matrix           [9]uint32
	Width            uint32 // 16.16 fixed point
	Height           uint32 // 16.16 fixed point
}

TrackHeader contains the track header box (tkhd) data.

Jump to

Keyboard shortcuts

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