Documentation
¶
Overview ¶
Package jpeg2000 implements a pure Go JPEG2000 codec.
This package encodes and decodes JPEG2000 codestreams (.j2k/.j2c) and JP2 files (.jp2). It supports both lossless (5/3 reversible wavelet) and lossy (9/7 irreversible wavelet) compression modes.
Decoding:
img, err := jpeg2000.Decode(reader)
if err != nil {
log.Fatal(err)
}
Encoding:
err := jpeg2000.Encode(writer, img, &jpeg2000.EncodeOptions{Lossless: true})
if err != nil {
log.Fatal(err)
}
The package registers itself with the image package for automatic format detection:
import _ "github.com/ajroetker/go-jpeg2000" img, _, err := image.Decode(reader)
Index ¶
- Variables
- func Analyze2D_53(coeffs [][]int32, width, height, levels int)
- func Analyze2D_53_At(coeffs [][]int32, tcx0, tcy0, tcx1, tcy1, levels int)
- func Analyze2D_97(coeffs [][]float64, width, height, levels int)
- func Analyze2D_97_At(coeffs [][]float64, tcx0, tcy0, tcx1, tcy1, levels int)
- func ComputeLayerPasses(subbands []*EncoderSubband, numLayers int) []map[int]int
- func ComputeLayerPassesRD(subbands []*EncoderSubband, numLayers int, targetRates []int) []map[int]int
- func Decode(r io.Reader) (image.Image, error)
- func DecodeConfig(r io.Reader) (image.Config, error)
- func DecodeWithOptions(r io.Reader, opts DecodeOptions) (image.Image, error)
- func DecodeWithUpsampling(r io.Reader) (image.Image, error)
- func Encode(w io.Writer, img image.Image, opts *EncodeOptions) error
- func InitSubbandTagTrees(sb *EncoderSubband)
- func ResetEncoderCodeBlocks(subbands []*EncoderSubband)
- func ResetSubbandTagTreeStates(subbands []*EncoderSubband)
- func Synthesize2D_53(coeffs [][]int32, width, height, levels int)
- func Synthesize2D_53_WithDims(coeffs [][]int32, resDims []ResBounds)
- func Synthesize2D_97(coeffs [][]float32, width, height, levels int)
- func Synthesize2D_97_WithDims(coeffs [][]float32, resDims []ResBounds)
- func WriteJP2File(w io.Writer, header *MainHeader, codestreamData []byte) error
- type CodeBlock
- type CodeBlockInfo
- type CodestreamWriter
- type DecodeOptions
- type Decoder
- type EncodeOptions
- type EncodedBlock
- type EncodedPass
- type EncoderCodeBlock
- type EncoderResolution
- type EncoderSubband
- type FileFormat
- type JP2ChannelDef
- type JP2ColorMethod
- type JP2ColorSpace
- type JP2ComponentMapping
- type JP2Metadata
- type JP2Palette
- type LayerAllocation
- type MainHeader
- func (h *MainHeader) ComponentCodeBlockSize(comp int) (int, int)
- func (h *MainHeader) ComponentCodeBlockStyle(comp int) byte
- func (h *MainHeader) ComponentDecompLevels(comp int) int
- func (h *MainHeader) ComponentHeight(comp int) int
- func (h *MainHeader) ComponentWaveletFilter(comp int) WaveletType
- func (h *MainHeader) ComponentWidth(comp int) int
- func (h *MainHeader) PrecinctSizeForRes(res, comp int) (int, int)
- type POCEntry
- type Packet
- type PacketEncoder
- func (pe *PacketEncoder) EncodeEmptyPacket() []byte
- func (pe *PacketEncoder) EncodePacket(layer, resolution, component, precinct int, subbands []*EncoderSubband, ...) []byte
- func (pe *PacketEncoder) EncodePacketWithEPH(layer, resolution, component, precinct int, subbands []*EncoderSubband, ...) []byte
- func (pe *PacketEncoder) EncodePacketWithSOP(layer, resolution, component, precinct int, subbands []*EncoderSubband, ...) []byte
- func (pe *PacketEncoder) EncodePacketsLRCP(resolutions [][]*EncoderResolution, layerPasses [][][]map[int]int) []byte
- type PacketTrace
- type Precinct
- type RateController
- type ResBounds
- type ResolutionLevel
- type Subband
- type SubbandType
- type TLMEntry
- type Tile
- type TileDecoder
- type TilePart
- type TruncationPoint
- type WaveletType
Constants ¶
This section is empty.
Variables ¶
var ( ErrInvalidMarker = errors.New("jpeg2000: invalid marker") ErrUnsupportedFormat = errors.New("jpeg2000: unsupported format") ErrInvalidHeader = errors.New("jpeg2000: invalid header") ErrTruncatedData = errors.New("jpeg2000: truncated data") ErrInvalidTile = errors.New("jpeg2000: invalid tile") ErrTooManyTiles = errors.New("jpeg2000: too many tiles") ErrImageTooLarge = errors.New("jpeg2000: image dimensions exceed limit") ErrUnsupportedWavelet = errors.New("jpeg2000: unsupported wavelet filter") ErrUnsupportedQuant = errors.New("jpeg2000: unsupported quantization") ErrDecodeFailed = errors.New("jpeg2000: decode failed") )
Functions ¶
func Analyze2D_53 ¶
Analyze2D_53 performs forward 2D 5/3 wavelet transform (lossless). Input: image samples in coeffs[y][x]. Output: subbands arranged as [LL, LH; HL, HH] per level. width, height: dimensions of the full image. levels: number of decomposition levels.
Per JPEG2000 standard (ITU-T T.800): forward transform applies vertical analysis first (columns), then horizontal analysis (rows). This is the opposite of the inverse transform which does horizontal then vertical.
func Analyze2D_53_At ¶ added in v0.13.0
Analyze2D_53_At is the forward 5/3 transform of a tile-component that begins at (tcx0, tcy0) on the reference grid and ends before (tcx1, tcy1).
The POSITION is not decoration. Each lifting step alternates between even and odd samples, and which of the two a subband's first sample is depends on where the tile begins -- not on how wide it is. Synthesize2D_53_WithDims takes each resolution's X0/Y0 for exactly this, calling it cas; the forward transform used to assume every tile began at zero, so a tile that did not was analysed in one phase and synthesised in the other.
Analyze2D_53 keeps the old shape and passes an origin of zero, which is what an untiled picture and every existing caller have.
func Analyze2D_97 ¶
Analyze2D_97 performs forward 2D 9/7 wavelet transform (lossy). Input: image samples in coeffs[y][x]. Output: subbands arranged as [LL, LH; HL, HH] per level. width, height: dimensions of the full image. levels: number of decomposition levels.
Per JPEG2000 standard (ITU-T T.800): forward transform applies vertical analysis first (columns), then horizontal analysis (rows). This is the opposite of the inverse transform which does horizontal then vertical.
func Analyze2D_97_At ¶ added in v0.13.0
Analyze2D_97_At is Analyze2D_53_At's twin for the irreversible filter: the same reason, the same arithmetic, the other wavelet.
func ComputeLayerPasses ¶
func ComputeLayerPasses( subbands []*EncoderSubband, numLayers int, ) []map[int]int
ComputeLayerPasses distributes coding passes across quality layers using a simple equal-pass distribution strategy. For more sophisticated rate-distortion optimization, the caller should compute passes per layer using the distortion values from EncodedPass.
This function assigns all passes of a code block to a single layer (layer 0). For multi-layer encoding, use rate-distortion optimization to determine optimal truncation points.
func ComputeLayerPassesRD ¶
func ComputeLayerPassesRD( subbands []*EncoderSubband, numLayers int, targetRates []int, ) []map[int]int
ComputeLayerPassesRD distributes coding passes across quality layers using rate-distortion optimization. Passes are assigned to layers based on their distortion reduction per byte (slope), with higher-slope passes going to earlier layers.
targetRates[layer] specifies the target bytes for each layer (cumulative). A targetRate of 0 means include all remaining data.
Returns passesPerBlock[layer][blockIdx] = number of new passes for that layer.
func DecodeConfig ¶
DecodeConfig returns the image configuration without full decoding
func DecodeWithOptions ¶
DecodeWithOptions decodes a JPEG2000 image with progressive decoding options. This allows partial decoding for faster preview or reduced memory usage.
Example usage:
// Decode only first 2 quality layers at half resolution
img, err := DecodeWithOptions(r, DecodeOptions{MaxLayers: 2, Reduce: 1})
func DecodeWithUpsampling ¶
DecodeWithUpsampling decodes a JPEG2000 image with component upsampling. Components with XRsiz/YRsiz > 1 are upsampled to full image dimensions.
func InitSubbandTagTrees ¶
func InitSubbandTagTrees(sb *EncoderSubband)
InitSubbandTagTrees initializes the tag tree values for a subband. Must be called after all code blocks have been added and before the first call to EncodePacket. Sets inclusion values to each block's FirstLayer and ZBP values to each block's ZeroBitPlanes.
For rate-distortion optimized encoding, the caller should set FirstLayer on each EncoderCodeBlock before calling this function. For simple single-layer encoding, set FirstLayer = 0 for all blocks that have data.
func ResetEncoderCodeBlocks ¶
func ResetEncoderCodeBlocks(subbands []*EncoderSubband)
ResetEncoderCodeBlocks resets the per-layer state of all code blocks in the provided subbands. This is useful when re-encoding with different layer assignments.
func ResetSubbandTagTreeStates ¶
func ResetSubbandTagTreeStates(subbands []*EncoderSubband)
ResetSubbandTagTreeStates resets the tag tree encoding states for all provided subbands. This should be called when re-encoding packets (e.g., for rate-distortion optimization) to ensure consistent state. Node values are preserved; only the incremental encoding states are cleared.
func Synthesize2D_53 ¶
Synthesize2D_53 performs full 2D inverse 5/3 wavelet transform coeffs: coefficient array organized as [LL, LH; HL, HH] subbands per level JPEG2000 standard: forward is V→H (columns then rows), inverse is H→V (rows then columns) width, height: dimensions of the full image levels: number of decomposition levels
func Synthesize2D_53_WithDims ¶
Synthesize2D_53_WithDims performs 2D inverse 5/3 wavelet transform using explicit resolution dimensions instead of computing them. resDims[i] contains bounds for resolution level i (0=coarsest) The X0/Y0 values are used to compute DWT parity (cas) for tiles at odd positions.
func Synthesize2D_97 ¶
func Synthesize2D_97_WithDims ¶
Synthesize2D_97_WithDims performs 2D inverse 9/7 wavelet transform using explicit resolution dimensions instead of computing them. resDims[i] contains bounds for resolution level i (0=coarsest) The X0/Y0 values are used to compute DWT parity (cas) for tiles at odd positions.
func WriteJP2File ¶
func WriteJP2File(w io.Writer, header *MainHeader, codestreamData []byte) error
WriteJP2File writes a complete JP2 file wrapping a JPEG2000 codestream. The JP2 file format (ITU-T T.800 Annex I) consists of a sequence of boxes:
- Signature Box (jP): file identification
- FileType Box (ftyp): brand and compatibility
- JP2 Header Box (jp2h): image header and color specification
- Contiguous Codestream Box (jp2c): the actual JPEG2000 codestream
Types ¶
type CodeBlock ¶
type CodeBlock struct {
X, Y int // Position in subband
Width, Height int // Dimensions
Data []byte // MQ-coded data
NumPasses int // Number of coding passes
ZeroBitPlanes int // Number of zero bit planes
Lblock int // Log2 of block size indicator
MagnitudeBitPlanes int // Number of magnitude bit planes (Mb = GuardBits + Exp - 1)
CodeBlockStyle byte // Codeblock coding style flags (from COD marker)
SegmentLengths []int // Per-segment lengths (used when ERTERM is set for pass termination)
}
CodeBlock represents a code block within a subband
type CodeBlockInfo ¶
type CodeBlockInfo struct {
X, Y int // Position in subband's code block grid
Width, Height int // Actual dimensions
ZeroBitPlanes int // Number of leading zero bit planes
TotalPasses int // Total coding passes received so far
Data []byte // Accumulated compressed data
Lblock int // Length indicator exponent (starts at 3)
IncludedLayer int // First layer where included (-1 if not included)
// Per-segment lengths when ERTERM or BYPASS mode is enabled.
// For ERTERM: one entry per pass.
// For BYPASS: one entry per segment (segments group passes by coding mode).
SegmentLengths []int
// contains filtered or unexported fields
}
CodeBlockInfo tracks decoding state of a code block
type CodestreamWriter ¶
type CodestreamWriter struct {
// contains filtered or unexported fields
}
CodestreamWriter writes a JPEG2000 codestream to an io.Writer. It produces valid codestreams conforming to ITU-T T.800 by writing the required marker segments (SOC, SIZ, COD, QCD) and tile data.
func NewCodestreamWriter ¶
func NewCodestreamWriter(w io.Writer, header *MainHeader) *CodestreamWriter
NewCodestreamWriter creates a new codestream writer that writes to w using the image parameters from header.
func (*CodestreamWriter) WriteEOC ¶
func (cw *CodestreamWriter) WriteEOC() error
WriteEOC writes the end-of-codestream marker (EOC).
func (*CodestreamWriter) WriteMainHeader ¶
func (cw *CodestreamWriter) WriteMainHeader() error
WriteMainHeader writes the main header of a JPEG2000 codestream. This includes the SOC marker followed by SIZ, COD, and QCD marker segments. Per ITU-T T.800, these must appear in this order before any tile-parts.
func (*CodestreamWriter) WriteTilePart ¶
func (cw *CodestreamWriter) WriteTilePart(tileIdx int, tileData []byte) error
WriteTilePart writes a complete tile-part consisting of an SOT marker segment, the SOD marker, and the tile bitstream data. tileIdx is the zero-based tile index and tileData contains the pre-assembled packet data for this tile.
The tile-part length (Psot) in the SOT marker includes the SOT marker itself (2 bytes), the SOT segment (10 bytes), the SOD marker (2 bytes), and the tile data length.
type DecodeOptions ¶
type DecodeOptions struct {
// MaxLayers limits the number of quality layers to decode.
// 0 means decode all layers (full quality).
// Values 1+ decode only that many layers (lower = faster, lower quality).
MaxLayers int
// Reduce specifies the resolution reduction factor.
// 0 means full resolution.
// 1 means half resolution (skip finest decomposition level).
// 2 means quarter resolution (skip two finest levels), etc.
// The output image dimensions are divided by 2^Reduce.
Reduce int
}
DecodeOptions controls progressive decoding behavior. This allows partial decoding for faster preview or reduced memory usage.
type Decoder ¶
type Decoder struct {
// contains filtered or unexported fields
}
Decoder holds state for decoding a JPEG2000 image
type EncodeOptions ¶
type EncodeOptions struct {
// Lossless selects the compression mode:
// true = 5/3 reversible wavelet + RCT (exact reconstruction)
// false = 9/7 irreversible wavelet + ICT (lossy)
Lossless bool
// Quality controls the compression ratio for lossy mode (0.0 to 1.0).
// 1.0 = highest quality (lowest compression).
// 0.5 = moderate quality.
// 0.0 = lowest quality (highest compression).
// Ignored when Lossless is true.
Quality float64
// TargetSize sets an explicit target file size in bytes.
// If > 0, overrides Quality. 0 means use Quality instead.
TargetSize int
// NumLayers sets the number of quality layers (default: 1).
NumLayers int
// TileWidth and TileHeight set tile dimensions.
// 0 means single tile (entire image).
TileWidth int
TileHeight int
// NumResolutions = NumDecompLevels + 1 (default: 6, meaning 5 decomposition levels).
NumResolutions int
// CodeBlockWidth and CodeBlockHeight (default: 64x64).
// Must be powers of 2, max 64.
CodeBlockWidth int
CodeBlockHeight int
// Progression order (default: LRCP = 0).
Progression byte
// FileFormat selects J2K (raw codestream) or JP2 (with file format boxes).
FileFormat FileFormat
}
EncodeOptions controls JPEG2000 encoding parameters.
type EncodedBlock ¶
type EncodedBlock struct {
// Per-pass encoded data
Passes []EncodedPass
// Number of significant (non-zero) bit planes
NumBitPlanes int
// Total number of coding passes
NumPasses int
// Zero bit planes (leading planes with no significant coefficients)
ZeroBitPlanes int
}
EncodedBlock holds the result of EBCOT encoding a single code block.
type EncodedPass ¶
type EncodedPass struct {
Data []byte // MQ-encoded (or raw) bytes for this pass
Length int // Length in bytes
Type int // Pass type: 0=SPP, 1=MRP, 2=Cleanup
BitPlane int // Which bit plane this pass encodes
Distortion float64 // Distortion reduction from this pass (for rate control)
}
EncodedPass holds data for a single coding pass.
type EncoderCodeBlock ¶
type EncoderCodeBlock struct {
Block *EncodedBlock
SubbandX int // X position in subband's code block grid
SubbandY int // Y position in subband's code block grid
// Per-layer state tracking
PassesIncluded int // Passes included in layers so far
FirstLayer int // First layer where included (-1 initially)
// Lblock tracks the length indicator exponent for this code block.
// Starts at 3 per ITU-T T.800. Incremented as needed to encode
// pass lengths that exceed the current bit budget.
Lblock int
}
EncoderCodeBlock holds a code block for encoding with its grid position.
func NewEncoderCodeBlock ¶
func NewEncoderCodeBlock(block *EncodedBlock, subbandX, subbandY int) *EncoderCodeBlock
NewEncoderCodeBlock creates an EncoderCodeBlock with properly initialized state.
type EncoderResolution ¶
type EncoderResolution struct {
Level int
Subbands []*EncoderSubband
}
EncoderResolution holds subbands for encoding.
type EncoderSubband ¶
type EncoderSubband struct {
Type SubbandType
Width int
Height int
CodeBlocksX int
CodeBlocksY int
CodeBlocks [][]*EncoderCodeBlock
// Tag trees for this subband's precinct.
// In the general case there is one pair of tag trees per precinct,
// but for the common single-precinct case we store them directly here.
InclusionTree *tagTree
ZBPTree *tagTree
}
EncoderSubband holds code blocks for encoding within a subband.
func NewEncoderSubband ¶
func NewEncoderSubband(sbType SubbandType, width, height, codeBlocksX, codeBlocksY int) *EncoderSubband
NewEncoderSubband creates an EncoderSubband with initialized tag trees. All code blocks must be added to CodeBlocks before calling EncodePacket.
type FileFormat ¶
type FileFormat int
FileFormat specifies the output file format.
const ( FormatJ2K FileFormat = iota // Raw codestream (.j2k/.j2c) FormatJP2 // JP2 file format with boxes (.jp2) )
type JP2ChannelDef ¶
type JP2ChannelDef struct {
Channel int // Channel number (Cn)
Type int // Channel type: 0=color, 1=opacity, 2=premult opacity, 0xFFFF=unspecified
Association int // Color association: 1=R/Y, 2=G/Cb, 3=B/Cr, 0=whole image, 0xFFFF=unspecified
}
JP2ChannelDef holds channel definition box (cdef) data per ITU-T T.800 I.5.3.6
type JP2ColorMethod ¶
type JP2ColorMethod uint8
JP2ColorMethod defines the color specification method
const ( JP2ColorEnumerated JP2ColorMethod = 1 // Enumerated colorspace JP2ColorICC JP2ColorMethod = 2 // Restricted ICC profile JP2ColorICCAny JP2ColorMethod = 3 // Any ICC profile (JP2 extensions) )
type JP2ColorSpace ¶
type JP2ColorSpace uint32
JP2ColorSpace defines enumerated color spaces per ITU-T T.800 Table I.1
const ( JP2ColorUnknown JP2ColorSpace = 0 JP2ColorBiLevel1 JP2ColorSpace = 1 // bi-level (1 = black) JP2ColorYCbCr1 JP2ColorSpace = 3 // YCbCr (ITU-R BT.601-5) JP2ColorYCbCr2 JP2ColorSpace = 4 // YCbCr (ITU-R BT.601-5 based on Rec.601) JP2ColorYCbCr3 JP2ColorSpace = 5 // YCbCr (ITU-R BT.709) JP2ColorPhotoYCC JP2ColorSpace = 9 // PhotoYCC JP2ColorCMY JP2ColorSpace = 11 // CMY JP2ColorCMYK JP2ColorSpace = 12 // CMYK JP2ColorYCCK JP2ColorSpace = 13 // YCCK JP2ColorCIELab JP2ColorSpace = 14 // CIELab (default illuminant/range) JP2ColorBiLevel2 JP2ColorSpace = 15 // bi-level (1 = white) JP2ColorSRGB JP2ColorSpace = 16 // sRGB JP2ColorGrayscale JP2ColorSpace = 17 // Greyscale JP2ColorSYCC JP2ColorSpace = 18 // sYCC (standard YCbCr) JP2ColorCIEJab JP2ColorSpace = 19 // CIEJab JP2ColorESRGB JP2ColorSpace = 20 // e-sRGB JP2ColorROMM JP2ColorSpace = 21 // ROMM-RGB JP2ColorYPbPr60 JP2ColorSpace = 22 // YPbPr (1125/60) JP2ColorYPbPr50 JP2ColorSpace = 23 // YPbPr (1250/50) JP2ColorESYCC JP2ColorSpace = 24 // e-sYCC )
type JP2ComponentMapping ¶
type JP2ComponentMapping struct {
Component int // Codestream component index (CMP)
MappingType int // 0=direct, 1=palette mapping (MTYP)
PaletteCol int // Palette column index (PCOL), only used if MappingType=1
}
JP2ComponentMapping holds component mapping box (cmap) data per ITU-T T.800 I.5.3.5
type JP2Metadata ¶
type JP2Metadata struct {
// From ihdr box
Height uint32
Width uint32
NumComps uint16
BitDepth int // From BPC field (bit depth - 1, plus sign bit)
Signed bool // Component sample signedness
Compression uint8 // Should be 7 for JP2
UnkC uint8 // Colorspace unknown flag
IPR uint8 // Intellectual property flag
// From colr box
ColorMethod JP2ColorMethod
Precedence uint8
Approx uint8
ColorSpace JP2ColorSpace // Only valid if ColorMethod == JP2ColorEnumerated
ICCProfile []byte // ICC profile data if ColorMethod == JP2ColorICC
// From res box (optional)
CaptureResX float64 // Capture resolution in grid points per meter
CaptureResY float64
DisplayResX float64 // Display resolution in grid points per meter
DisplayResY float64
// From pclr box (palette)
Palette *JP2Palette
// From cmap box (component mapping)
ComponentMap []JP2ComponentMapping
// From cdef box (channel definition)
ChannelDefs []JP2ChannelDef
// Metadata boxes (optional)
UUIDData [][]byte // Raw UUID box contents
XMLData [][]byte // Raw XML box contents
// contains filtered or unexported fields
}
JP2Metadata holds parsed JP2 container information
func (*JP2Metadata) GetChannelOrder ¶
func (m *JP2Metadata) GetChannelOrder() []int
GetChannelOrder returns the output channel order based on cdef associations. Returns a mapping where result[outputIndex] = inputChannelIndex. For RGB output: association 1=R, 2=G, 3=B.
func (*JP2Metadata) IsGrayscale ¶
func (m *JP2Metadata) IsGrayscale() bool
IsGrayscale returns true if the color space is grayscale
func (*JP2Metadata) IsSRGB ¶
func (m *JP2Metadata) IsSRGB() bool
IsSRGB returns true if the color space is sRGB
func (*JP2Metadata) IsYCbCr ¶
func (m *JP2Metadata) IsYCbCr() bool
IsYCbCr returns true if the color space is a YCbCr variant
func (*JP2Metadata) NeedsChannelReorder ¶
func (m *JP2Metadata) NeedsChannelReorder() bool
NeedsChannelReorder returns true if cdef specifies a non-identity channel mapping for color channels (e.g., BGR instead of RGB).
type JP2Palette ¶
type JP2Palette struct {
NumEntries int // Number of palette entries (NE)
NumColumns int // Number of columns/channels (NPC)
BitDepths []int // Bit depth per column (Bi)
Signed []bool // Whether each column is signed
Entries [][]int // [entry][column] lookup values
}
JP2Palette holds palette box (pclr) data per ITU-T T.800 I.5.3.4
type LayerAllocation ¶
type LayerAllocation struct {
// NumPasses[i] = number of passes for block i in this layer
NumPasses []int
}
LayerAllocation specifies which passes of each block go into a quality layer.
type MainHeader ¶
type MainHeader struct {
// From SIZ marker
Width int // Image width
Height int // Image height
XOsiz int // Horizontal offset
YOsiz int // Vertical offset
TileWidth int // Tile width
TileHeight int // Tile height
XTOsiz int // Tile grid horizontal offset
YTOsiz int // Tile grid vertical offset
NumComps int // Number of components
BitDepth []int // Bit depth per component
Signed []bool // Signed flag per component
XRsiz []int // Horizontal sample separation
YRsiz []int // Vertical sample separation
// From COD marker
ProgressionOrder byte // 0=LRCP, 1=RLCP, 2=RPCL, 3=PCRL, 4=CPRL
NumLayers int // Number of quality layers
MCT bool // Multiple component transform used
NumDecompLevels int // Number of decomposition levels
CodeBlockWidth int // Code block width (power of 2)
CodeBlockHeight int // Code block height (power of 2)
CodeBlockStyle byte // Code block coding style flags
WaveletFilter WaveletType
UsesSOP bool // SOP (Start of Packet) markers present
UsesEPH bool // EPH (End of Packet Header) markers present
// Precinct sizes per resolution level (index 0 = resolution 0, lowest)
// Each entry is [width_exponent, height_exponent] where size = 2^exponent
// If nil, default precinct size (15,15) = 32768x32768 (effectively whole tile)
PrecinctSizes [][2]int
// From QCD marker (default quantization for all components)
QuantStyle byte // 0=none, 1=scalar derived, 2=scalar expounded (may be overridden by QCC)
OriginalQuantStyle byte // Original QCD quantStyle before any QCC override
GuardBits int // Number of guard bits
StepSizes []float64 // Quantization step sizes
Exponents []int // Step size exponents (may be overridden by QCC for component 0)
Mantissas []int // Step size mantissas (may be overridden by QCC for component 0)
// Original QCD values before any QCC override (used for components without QCC)
OriginalExponents []int // Original QCD exponents
OriginalMantissas []int // Original QCD mantissas
// Per-component quantization (from QCC markers)
// If set, these override the default QCD values for specific components
// Index = component number
CompQuantStyle []byte // Per-component quant style
CompExponents [][]int // Per-component exponents
CompMantissas [][]int // Per-component mantissas
// Per-component coding style (from COC markers)
// If set, these override the default COD values for specific components
// Index = component number, value is number of decomposition levels
// A value of -1 means use default (NumDecompLevels)
CompDecompLevels []int // Per-component decomposition levels
CompPrecinctSizes [][][2]int // Per-component precinct sizes [comp][res] (nil = use default)
CompCodeBlockWidth []int // Per-component code block width (0 = use default)
CompCodeBlockHeight []int // Per-component code block height (0 = use default)
CompCodeBlockStyle []byte // Per-component code block style (0xFF = use default)
CompWaveletFilter []WaveletType // Per-component wavelet filter (0xFF = use default)
// From POC marker (if present, overrides COD progression order)
POCEntries []POCEntry // Progression order change entries
// From TLM marker (tile-part lengths for random access)
TLMEntries []TLMEntry // Tile-part length entries
// PPM (Packed Packet Headers in Main header) data
// When present, packet headers are stored here instead of in the tile data stream
// Per ITU-T T.800, multiple PPM segments are concatenated in order of Zppm index
PPMHeaders []byte
// TilePartOrder records the tile index for each tile-part in codestream order.
// Used by distributePPMHeaders to correctly assign PPM data per tile-part.
TilePartOrder []int
// Computed
NumXTiles int
NumYTiles int
NumTiles int
// contains filtered or unexported fields
}
MainHeader contains parsed image metadata
func (*MainHeader) ComponentCodeBlockSize ¶
func (h *MainHeader) ComponentCodeBlockSize(comp int) (int, int)
ComponentCodeBlockSize returns the code block width and height for a component. Per-component COC overrides take precedence over the default COD values.
func (*MainHeader) ComponentCodeBlockStyle ¶
func (h *MainHeader) ComponentCodeBlockStyle(comp int) byte
ComponentCodeBlockStyle returns the code block style for a component.
func (*MainHeader) ComponentDecompLevels ¶
func (h *MainHeader) ComponentDecompLevels(comp int) int
ComponentDecompLevels returns the number of decomposition levels for a component. This accounts for per-component COC marker overrides. If no override exists, returns the default from COD marker.
func (*MainHeader) ComponentHeight ¶
func (h *MainHeader) ComponentHeight(comp int) int
ComponentHeight returns the height of a component accounting for subsampling Per ITU-T T.800 Annex B, equation B-2:
tcy0 = ceil(YOsiz / YRsiz) tcy1 = ceil(Ysiz / YRsiz) compHeight = tcy1 - tcy0
This is NOT the same as ceil((Ysiz - YOsiz) / YRsiz) when YOsiz > 0.
func (*MainHeader) ComponentWaveletFilter ¶
func (h *MainHeader) ComponentWaveletFilter(comp int) WaveletType
ComponentWaveletFilter returns the wavelet filter for a component.
func (*MainHeader) ComponentWidth ¶
func (h *MainHeader) ComponentWidth(comp int) int
ComponentWidth returns the width of a component accounting for subsampling Per ITU-T T.800 Annex B, equation B-2:
tcx0 = ceil(XOsiz / XRsiz) tcx1 = ceil(Xsiz / XRsiz) compWidth = tcx1 - tcx0
This is NOT the same as ceil((Xsiz - XOsiz) / XRsiz) when XOsiz > 0.
func (*MainHeader) PrecinctSizeForRes ¶
func (h *MainHeader) PrecinctSizeForRes(res, comp int) (int, int)
PrecinctSizeForRes returns the precinct size exponents (PPx, PPy) for a given resolution level and component. Per-component COC overrides take precedence over the default COD precinct sizes.
type POCEntry ¶
type POCEntry struct {
RSpoc int // Resolution level start
CSpoc int // Component start
LYEpoc int // Layer end (exclusive)
REpoc int // Resolution level end (exclusive)
CEpoc int // Component end (exclusive)
Ppoc byte // Progression order for this entry
}
POCEntry represents a single progression order change entry
type PacketEncoder ¶
type PacketEncoder struct {
// contains filtered or unexported fields
}
PacketEncoder assembles encoded code blocks into JPEG2000 packets.
func NewPacketEncoder ¶
func NewPacketEncoder(header *MainHeader) *PacketEncoder
NewPacketEncoder creates a new packet encoder.
func (*PacketEncoder) EncodeEmptyPacket ¶
func (pe *PacketEncoder) EncodeEmptyPacket() []byte
EncodeEmptyPacket encodes an empty packet (no code block data). Per ITU-T T.800, this is a single 0-bit followed by byte alignment.
func (*PacketEncoder) EncodePacket ¶
func (pe *PacketEncoder) EncodePacket( layer, resolution, component, precinct int, subbands []*EncoderSubband, passesPerBlock map[int]int, ) []byte
EncodePacket encodes a single packet for one quality layer, one resolution, one component, and one precinct.
passesPerBlock maps a linear block index (y*CodeBlocksX + x) to the number of NEW coding passes to include for that block in this layer. Blocks not present in the map (or with value 0) contribute no data to this packet.
Returns the encoded packet bytes (header + body).
func (*PacketEncoder) EncodePacketWithEPH ¶
func (pe *PacketEncoder) EncodePacketWithEPH( layer, resolution, component, precinct int, subbands []*EncoderSubband, passesPerBlock map[int]int, ) []byte
EncodePacketWithEPH encodes a packet with an EPH (End of Packet Header) marker inserted between the packet header and body. Per ITU-T T.800, the EPH marker is: 0xFF92 (2 bytes).
func (*PacketEncoder) EncodePacketWithSOP ¶
func (pe *PacketEncoder) EncodePacketWithSOP( layer, resolution, component, precinct int, subbands []*EncoderSubband, passesPerBlock map[int]int, packetSeqNum int, ) []byte
EncodePacketWithSOP encodes a packet preceded by a SOP (Start of Packet) marker. Per ITU-T T.800, the SOP marker has the structure:
0xFF91 (2 bytes) + Lsop=0x0004 (2 bytes) + Nsop (2 bytes)
where Nsop is the packet sequence number (mod 65536).
func (*PacketEncoder) EncodePacketsLRCP ¶
func (pe *PacketEncoder) EncodePacketsLRCP( resolutions [][]*EncoderResolution, layerPasses [][][]map[int]int, ) []byte
EncodePacketsLRCP encodes all packets for a tile in LRCP progression order. This is the most common progression order: Layer, Resolution, Component, Position.
resolutions[component][resolution] provides the encoder subbands. layerPasses[layer][component][resolution][blockIdx] provides the number of new passes for each code block in each layer.
Returns all encoded packets concatenated.
type PacketTrace ¶
type PacketTrace struct {
Layer int // Quality layer
Resolution int // Resolution level
Component int // Component index
PrecinctX int // Precinct X index
PrecinctY int // Precinct Y index
BytePosBefore int // Byte position before parsing
BitPosBefore int // Bit position before parsing
BytePosAfter int // Byte position after parsing
BitPosAfter int // Bit position after parsing
EmptyBit int // Value of empty packet indicator (0 or 1)
NumEntries int // Number of code block entries
DataRead int // Bytes of code block data read
FirstBytes []byte // First few bytes at parse start (for debugging)
SubbandEntries []int // Per-subband entry counts (for debugging)
}
PacketTrace captures parsing state for debugging
type Precinct ¶
type Precinct struct {
X, Y int // Precinct index within resolution level
Width, Height int // Precinct dimensions in samples
// Code block range within each subband for this precinct
// For subband sb: iterate cb[cbY0:cbY1][cbX0:cbX1]
CBX0, CBY0 int // Start code block indices (inclusive)
CBX1, CBY1 int // End code block indices (exclusive)
}
Precinct is a rectangular region containing code blocks
type RateController ¶
type RateController struct {
// contains filtered or unexported fields
}
RateController performs PCRD-opt rate-distortion optimization.
func NewRateController ¶
func NewRateController(blocks []*EncodedBlock) *RateController
NewRateController creates a rate controller for the given encoded blocks.
func (*RateController) OptimizeLayers ¶
func (rc *RateController) OptimizeLayers(targetBytesPerLayer []int) []LayerAllocation
OptimizeLayers performs multi-layer PCRD-opt. targetBytesPerLayer[i] = cumulative target bytes for layer i. Returns LayerAllocation for each layer.
func (*RateController) OptimizeSingleLayer ¶
func (rc *RateController) OptimizeSingleLayer(targetBytes int) []int
OptimizeSingleLayer finds optimal truncation for a single quality layer to achieve the target byte count. Returns the number of passes to include for each block.
type ResBounds ¶
ResBounds holds resolution-level bounds for DWT synthesis X0, Y0 are the image-space origin (trX0, trY0) used for parity calculation
type ResolutionLevel ¶
type ResolutionLevel struct {
Level int // 0 = LL band only, 1+ = HL, LH, HH subbands
Width int
Height int
X0, Y0 int // Image-space origin (trX0, trY0) for DWT parity calculation
Subbands []*Subband
Precincts []*Precinct
}
ResolutionLevel represents one resolution level in the wavelet decomposition
type Subband ¶
type Subband struct {
Type SubbandType
Width, Height int
// X0, Y0 are the subband origin in image-space coordinates (tbX0, tbY0).
// Per ITU-T T.800 equation B-16, these are derived from resolution bounds (trX0, trY0).
X0, Y0 int
CodeBlocksX int // Number of code blocks horizontally
CodeBlocksY int // Number of code blocks vertically
CodeBlocks [][]*CodeBlockInfo
// Precinct grid parameters.
// PrcGridX0/Y0: absolute index of the first precinct overlapping the resolution.
// Computed as floor(trX0 / 2^PPx). This is the RESOLUTION-level grid origin,
// shared by all subbands within the resolution. Using the subband origin instead
// would give incorrect results when sbX0/prcW != trX0/(2*prcW).
PrcGridX0, PrcGridY0 int
// PrecinctWidth/Height: precinct size in subband coordinates.
// For detail subbands: 2^(PPx-1) × 2^(PPy-1). For LL: 2^PPx × 2^PPy.
PrecinctWidth int
PrecinctHeight int
// Per-precinct tag trees (JPEG2000 spec: each precinct has its own tag trees)
// Indexed by [precinctY * numPrecinctsX + precinctX]
PrecinctInclusionTrees []*tagTree
PrecinctZBPTrees []*tagTree
NumPrecinctsX int
NumPrecinctsY int
}
Subband within a resolution level
type SubbandType ¶
type SubbandType int
SubbandType represents different subband orientations
const ( SubbandLL SubbandType = iota SubbandHL SubbandLH SubbandHH )
func (SubbandType) String ¶
func (s SubbandType) String() string
type TLMEntry ¶
type TLMEntry struct {
TileIndex int // Tile index (0-65534, or -1 if not specified in TLM)
TilePartLen int // Length of tile-part in bytes (includes SOT marker)
}
TLMEntry represents a tile-part length entry from TLM marker. Per ITU-T T.800, TLM markers provide tile-part lengths for random access.
type Tile ¶
type Tile struct {
Index int
X0, Y0 int // Tile origin in image coords
X1, Y1 int // Tile end in image coords
TileParts []*TilePart
// ROI (Region of Interest) shift values per component
// From RGN marker in tile-part header
// If ROIShift[c] > 0, coefficients for component c need to be de-shifted
ROIShift []int
// Tile-specific coding style overrides from tile-part header COD marker
// If HasTileCOD is true, use these instead of main header values
HasTileCOD bool
TileProgressionOrder byte // SGcod: progression order (0=LRCP, 1=RLCP, 2=RPCL, 3=PCRL, 4=CPRL)
TileNumLayers int // SGcod: number of layers
TileCodeBlockStyle byte
TileNumDecompLevels int
TileCodeBlockWidthExp byte // SPcod: code block width exponent (offset from 2)
TileCodeBlockHeightExp byte // SPcod: code block height exponent (offset from 2)
TileWaveletFilter WaveletType
TilePrecinctSizes [][2]byte // Per-resolution precinct sizes (PPx, PPy) from tile COD
// Tile-specific quantization overrides from tile-part header QCD marker
// If HasTileQCD is true, use these instead of main header QCD values
HasTileQCD bool
TileQuantStyle byte
TileGuardBits int
TileExponents []int
TileMantissas []int
// PPT (Packed Packet Headers) data
// When present, packet headers are stored here instead of in the tile data stream
// Per ITU-T T.800, multiple PPT segments are concatenated in order of Zppt index
PPTHeaders []byte
// POC (Progression Order Change) entries from tile-part header
// When present, overrides main header POC/COD progression order for this tile
POCEntries []POCEntry
// contains filtered or unexported fields
}
Tile represents a single tile
type TileDecoder ¶
type TileDecoder struct {
// Trace collects packet parsing traces when non-nil (for debugging)
Trace []PacketTrace
// contains filtered or unexported fields
}
TileDecoder handles tile-level packet parsing and decoding
func (*TileDecoder) EnableTracing ¶
func (td *TileDecoder) EnableTracing()
EnableTracing enables packet parsing trace collection
type TruncationPoint ¶
type TruncationPoint struct {
BlockIndex int // Index into the blocks array
PassIndex int // Number of passes to include (1-based: pass 0 means include first pass)
Bytes int // Cumulative bytes up to this pass
Distortion float64 // Cumulative distortion reduction up to this pass
Slope float64 // R-D slope = ΔD/ΔR (distortion reduction per byte)
}
TruncationPoint represents a truncation point for a code block pass.
type WaveletType ¶
type WaveletType int
WaveletType indicates the wavelet filter used
const ( Wavelet53 WaveletType = iota // 5/3 reversible (lossless) Wavelet97 // 9/7 irreversible (lossy) )