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
- Variables
- type Box
- type FrameInfo
- type HandlerReference
- type JP2Header
- type Media
- type MediaHeader
- type Movie
- type MovieHeader
- type Reader
- func (r *Reader) ExtractFrame(trackIdx, frameIdx int) ([]byte, error)
- func (r *Reader) GetFrameInfo(trackIdx, frameIdx int) (*FrameInfo, error)
- func (r *Reader) GetMovie() *Movie
- func (r *Reader) GetVideoTracks() []*Track
- func (r *Reader) IsFrameIndependent(trackIdx, frameIdx int) bool
- func (r *Reader) Parse() error
- type SampleDescription
- type SampleEntry
- type SampleTable
- type SampleToChunkEntry
- type TimeToSampleEntry
- type Track
- type TrackHeader
Constants ¶
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
const ( HandlerTypeVideo = "vide" // Video handler HandlerTypeAudio = "soun" // Sound handler HandlerTypeHint = "hint" // Hint handler )
Handler types
Variables ¶
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
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 ¶
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 ¶
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).
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 (*Reader) ExtractFrame ¶
ExtractFrame extracts a video frame as raw JP2 codestream data.
func (*Reader) GetFrameInfo ¶
GetFrameInfo returns information about a specific frame.
func (*Reader) GetVideoTracks ¶
GetVideoTracks returns all video tracks in the movie.
func (*Reader) IsFrameIndependent ¶
IsFrameIndependent returns true if the frame can be decoded independently. For MJ2, all frames are independent (intra-coded).
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 ¶
DurationSeconds returns the track duration in seconds.
func (*Track) FrameCount ¶
FrameCount returns the number of frames/samples in this track.
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.