Documentation
¶
Index ¶
- Constants
- Variables
- type BitReader
- type CoefficientBuffer
- func (cb *CoefficientBuffer) GetBlock(component, block int) []int
- func (cb *CoefficientBuffer) GetCoefficient(component, block, coeff int) int
- func (cb *CoefficientBuffer) IsNonZero(component, block, coeff int) bool
- func (cb *CoefficientBuffer) RefineAC(component, block, coeff, bit, al int) error
- func (cb *CoefficientBuffer) RefineDC(component, block, bit, al int) error
- func (cb *CoefficientBuffer) Reset()
- func (cb *CoefficientBuffer) SetACFirstScan(component, block, coeff, value, al int) error
- func (cb *CoefficientBuffer) SetCoefficient(component, block, coeff, value int) error
- func (cb *CoefficientBuffer) SetDCFirstScan(component, block, value, al int) error
- type Component
- type DefaultValidator
- func (*DefaultValidator) SafeAdd(a, b int) (int, error)
- func (*DefaultValidator) SafeMultiply(a, b int) (int, error)
- func (*DefaultValidator) SafeSubtract(a, b int) (int, error)
- func (*DefaultValidator) ValidateComponentCount(count int) error
- func (*DefaultValidator) ValidateDimensions(width, height int) error
- func (*DefaultValidator) ValidatePrecision(precision int) error
- func (v *DefaultValidator) ValidateScanHeader(ss, se, ah, al, nf int) error
- func (*DefaultValidator) ValidateSpectralSelection(ss, se int) error
- func (*DefaultValidator) ValidateSuccessiveApproximation(ah, al int) error
- type EOBTracker
- type Frame
- type FrameParser
- type HuffmanTable
- type Scan
- type ScanComponent
- type ScanDecoder
- type ScanParser
- type ScanTracker
- type Validator
Constants ¶
const ( // MaxScans is the maximum number of scans allowed (security limit) MaxScans = 100 // MaxCoefficients is the maximum coefficient buffer size (512MB / 4 bytes per int) MaxCoefficients = 134217728 // MaxBlocksPerComponent prevents OOM attacks MaxBlocksPerComponent = 16777216 // 16M blocks // MaxSpectralIndex is the maximum DCT coefficient index (0-63) MaxSpectralIndex = 63 // MaxSuccessiveApprox is the maximum successive approximation value MaxSuccessiveApprox = 13 // MaxComponents is the maximum number of color components MaxComponents = 4 // ValidPrecision8 is 8-bit sample precision ValidPrecision8 = 8 // ValidPrecision12 is 12-bit sample precision ValidPrecision12 = 12 )
Constants for progressive JPEG limits
const MaxEOBRun = 32767
MaxEOBRun is the maximum allowed EOB run length (2^14 for EOB14)
Variables ¶
var ( // ErrInvalidScanHeader is the umbrella sentinel returned by the SOS // validator whenever any T.81 G.1.1.1.1 rule is violated. Specific // violations wrap this with a descriptive message. ErrInvalidScanHeader = errors.New("invalid progressive SOS scan header") // ErrInvalidDCScan indicates a DC scan (Ss=0) violates T.81 G.1.1.1.1: // DC scans require Se=0. ErrInvalidDCScan = errors.New("invalid DC scan parameters") // ErrInvalidACScan indicates an AC scan (Ss>=1) violates T.81 G.1.1.1.1: // AC scans require Se>=Ss, Se<=63, and Nf=1 (a single component). ErrInvalidACScan = errors.New("invalid AC scan parameters") // ErrInvalidRefinement indicates a refinement scan (Ah!=0) has Al that // is not exactly Ah-1, violating T.81 G.1.1.1.1's successive-approximation // rule. ErrInvalidRefinement = errors.New("invalid successive-approximation refinement") )
Sentinel errors for SOS scan-header validation per ITU-T T.81 §G.1.1.1.1. These are wrappable (%w) so callers can distinguish a scan-header rejection from other validation failures (precision, dimensions, safe-arithmetic) with errors.Is.
var ErrInvalidMarker = fmt.Errorf("invalid marker")
ErrInvalidMarker indicates an invalid marker was encountered during progressive JPEG parsing.
Functions ¶
This section is empty.
Types ¶
type BitReader ¶
type BitReader struct {
// contains filtered or unexported fields
}
BitReader reads bits from an io.Reader with byte stuffing handling. In JPEG entropy-coded segments, 0xFF bytes are followed by 0x00 (stuffing).
func NewBitReader ¶
NewBitReader creates a new bit reader.
func (*BitReader) ReadBit ¶
ReadBit reads a single bit from the stream. Returns the bit value (0 or 1) and an error if EOF or read error.
type CoefficientBuffer ¶
type CoefficientBuffer struct {
// Width is the image width in pixels
Width int
// Height is the image height in pixels
Height int
// ComponentCount is the number of color components
ComponentCount int
// BlocksH is the number of 8x8 blocks horizontally
BlocksH int
// BlocksV is the number of 8x8 blocks vertically
BlocksV int
// contains filtered or unexported fields
}
CoefficientBuffer stores DCT coefficients across progressive scans. In progressive JPEG, coefficients are built up over multiple scans, so the buffer must persist and accumulate data across scans.
func NewCoefficientBuffer ¶
func NewCoefficientBuffer(width, height, components int, validator Validator) (*CoefficientBuffer, error)
NewCoefficientBuffer creates a new coefficient buffer for the given image dimensions. Returns an error if dimensions are invalid or would cause memory exhaustion.
func (*CoefficientBuffer) GetBlock ¶
func (cb *CoefficientBuffer) GetBlock(component, block int) []int
GetBlock returns all 64 coefficients for a block. Returns nil if indices are invalid.
func (*CoefficientBuffer) GetCoefficient ¶
func (cb *CoefficientBuffer) GetCoefficient(component, block, coeff int) int
GetCoefficient retrieves a coefficient value. Returns 0 if indices are out of bounds (for safety in read operations).
func (*CoefficientBuffer) IsNonZero ¶
func (cb *CoefficientBuffer) IsNonZero(component, block, coeff int) bool
IsNonZero returns true if the coefficient has been set to a non-zero value.
func (*CoefficientBuffer) RefineAC ¶
func (cb *CoefficientBuffer) RefineAC(component, block, coeff, bit, al int) error
RefineAC adds a refinement bit to an AC coefficient. For refinement scan (Ah != 0), a single bit is added at position Al.
func (*CoefficientBuffer) RefineDC ¶
func (cb *CoefficientBuffer) RefineDC(component, block, bit, al int) error
RefineDC adds a refinement bit to the DC coefficient. For refinement scan (Ah != 0), a single bit is added at position Al.
func (*CoefficientBuffer) Reset ¶
func (cb *CoefficientBuffer) Reset()
Reset clears all coefficients to zero. Useful for starting a new image decode.
func (*CoefficientBuffer) SetACFirstScan ¶
func (cb *CoefficientBuffer) SetACFirstScan(component, block, coeff, value, al int) error
SetACFirstScan sets an AC coefficient for a block in the first scan. For first scan (Ah=0), the value is shifted left by Al bits.
func (*CoefficientBuffer) SetCoefficient ¶
func (cb *CoefficientBuffer) SetCoefficient(component, block, coeff, value int) error
SetCoefficient sets a coefficient value with bounds checking.
func (*CoefficientBuffer) SetDCFirstScan ¶
func (cb *CoefficientBuffer) SetDCFirstScan(component, block, value, al int) error
SetDCFirstScan sets the DC coefficient for a block in the first scan. For first scan (Ah=0), the value is shifted left by Al bits. This stores the most significant bits, leaving lower bits for refinement.
type Component ¶
type Component struct {
// ID is the component identifier (1-255)
ID int
// HorizontalSampling is the horizontal sampling factor (1-4)
HorizontalSampling int
// VerticalSampling is the vertical sampling factor (1-4)
VerticalSampling int
// QuantTableID is the quantization table selector (0-3)
QuantTableID int
}
Component represents a single color component in the frame.
type DefaultValidator ¶
type DefaultValidator struct{}
DefaultValidator implements Validator with standard checks.
func NewValidator ¶
func NewValidator() *DefaultValidator
NewValidator creates a new default validator.
func (*DefaultValidator) SafeAdd ¶
func (*DefaultValidator) SafeAdd(a, b int) (int, error)
SafeAdd performs addition with overflow checking.
func (*DefaultValidator) SafeMultiply ¶
func (*DefaultValidator) SafeMultiply(a, b int) (int, error)
SafeMultiply performs multiplication with overflow checking.
func (*DefaultValidator) SafeSubtract ¶
func (*DefaultValidator) SafeSubtract(a, b int) (int, error)
SafeSubtract performs subtraction with underflow checking.
func (*DefaultValidator) ValidateComponentCount ¶
func (*DefaultValidator) ValidateComponentCount(count int) error
ValidateComponentCount validates number of components.
func (*DefaultValidator) ValidateDimensions ¶
func (*DefaultValidator) ValidateDimensions(width, height int) error
ValidateDimensions validates width and height.
func (*DefaultValidator) ValidatePrecision ¶
func (*DefaultValidator) ValidatePrecision(precision int) error
ValidatePrecision validates sample precision (must be 8 or 12 for progressive DCT).
func (*DefaultValidator) ValidateScanHeader ¶
func (v *DefaultValidator) ValidateScanHeader(ss, se, ah, al, nf int) error
ValidateScanHeader enforces the SOS scan-header constraints defined in ITU-T T.81 §G.1.1.1.1 for progressive-mode JPEGs. The caller passes the numeric tuple parsed from the SOS marker — spectral start/end, successive- approximation high/low, and the component count Nf — and receives a wrapped error describing the exact violated rule on failure, or nil on success.
Rules enforced, per T.81 G.1.1.1.1:
- DC scan (Ss=0): Se must equal 0; any Nf in 1..MaxComponents is allowed.
- AC scan (Ss>=1): Se must satisfy Ss<=Se<=63 and Nf must equal 1 (AC scans may contain only a single component).
- First scan (Ah=0): no refinement constraint on Al beyond the general 0..13 range handled below.
- Refinement scan (Ah!=0): Al must equal Ah-1, matching the successive- approximation one-bit-at-a-time rule.
Errors are returned wrapping the appropriate sentinel (ErrInvalidDCScan, ErrInvalidACScan, ErrInvalidRefinement) via fmt.Errorf("...: %w", ...) so callers can dispatch on errors.Is. ValidateScanHeader itself does not panic; out-of-range scalar inputs (Ss/Se outside 0..63, Ah/Al outside 0..13, or Nf outside 1..MaxComponents) fall through to ErrInvalidScanHeader with a descriptive wrapper.
Ordering matters: scalar-range checks run first so the DC/AC rules below can assume bounded inputs. The Se<Ss check is intentionally deferred to the AC branch rather than subsumed by ValidateSpectralSelection, so an AC-mode violation (Ss>=1, Se<Ss) wraps ErrInvalidACScan rather than the umbrella ErrInvalidScanHeader — callers dispatching on errors.Is(err, ErrInvalidACScan) get a more specific signal.
func (*DefaultValidator) ValidateSpectralSelection ¶
func (*DefaultValidator) ValidateSpectralSelection(ss, se int) error
ValidateSpectralSelection validates Ss and Se parameters.
func (*DefaultValidator) ValidateSuccessiveApproximation ¶
func (*DefaultValidator) ValidateSuccessiveApproximation(ah, al int) error
ValidateSuccessiveApproximation validates Ah and Al parameters.
type EOBTracker ¶
type EOBTracker struct {
// EOBRun is the remaining number of blocks to skip
EOBRun int
}
EOBTracker tracks End-of-Block runs in progressive AC scans. In progressive JPEG, EOBn symbols (n=0-14) indicate that the next 2^n blocks have no more non-zero coefficients in the current spectral band.
func (*EOBTracker) ConsumeEOB ¶
func (e *EOBTracker) ConsumeEOB() bool
ConsumeEOB decrements the EOB run counter. Returns true if there was a run to consume, false if run was already 0.
func (*EOBTracker) HasEOBRun ¶
func (e *EOBTracker) HasEOBRun() bool
HasEOBRun returns true if there are remaining blocks in the EOB run.
func (*EOBTracker) SetEOBRun ¶
func (e *EOBTracker) SetEOBRun(run int)
SetEOBRun sets the EOB run length. This is called when an EOBn symbol is decoded.
func (*EOBTracker) SetEOBRunSafe ¶
func (e *EOBTracker) SetEOBRunSafe(run int) error
SetEOBRunSafe sets the EOB run length with overflow protection.
type Frame ¶
type Frame struct {
// Precision is the sample precision in bits (8 or 12 for progressive)
Precision int
// Height is the image height in pixels
Height int
// Width is the image width in pixels
Width int
// Components contains the color component specifications
Components []Component
}
Frame represents a progressive JPEG frame (SOF2).
type FrameParser ¶
type FrameParser struct {
// contains filtered or unexported fields
}
FrameParser parses progressive JPEG frame markers (SOF2).
func NewFrameParser ¶
func NewFrameParser(validator Validator) *FrameParser
NewFrameParser creates a new frame parser with the given validator.
type HuffmanTable ¶
type HuffmanTable struct {
// contains filtered or unexported fields
}
HuffmanTable represents a Huffman decoding table.
func NewHuffmanTable ¶
func NewHuffmanTable(bits [17]int, huffval []int) *HuffmanTable
NewHuffmanTable creates a new Huffman table from BITS and HUFFVAL. bits[i] is the number of codes with length i+1 (bits[0] unused). huffval contains the symbol values in order.
type Scan ¶
type Scan struct {
// Components lists the components in this scan
Components []ScanComponent
// SpectralStart is the first DCT coefficient in this scan (Ss, 0-63)
SpectralStart int
// SpectralEnd is the last DCT coefficient in this scan (Se, 0-63)
SpectralEnd int
// SuccApproxHigh is the successive approximation bit position high (Ah, 0-13)
SuccApproxHigh int
// SuccApproxLow is the successive approximation bit position low (Al, 0-13)
SuccApproxLow int
}
Scan represents a single scan in a progressive JPEG.
func (*Scan) IsFirstScan ¶
IsFirstScan returns true if this is the first scan for its coefficients.
func (*Scan) IsRefinementScan ¶
IsRefinementScan returns true if this is a refinement scan.
type ScanComponent ¶
type ScanComponent struct {
// ComponentSelector identifies the component (matches Component.ID)
ComponentSelector int
// DCTableSelector is the DC Huffman/arithmetic table (0-3)
DCTableSelector int
// ACTableSelector is the AC Huffman/arithmetic table (0-3)
ACTableSelector int
}
ScanComponent represents a component's parameters within a scan.
type ScanDecoder ¶
type ScanDecoder struct {
// contains filtered or unexported fields
}
ScanDecoder decodes entropy-coded data from progressive JPEG scans. It handles spectral selection and successive approximation for both first scans (Ah=0) and refinement scans (Ah>0).
func NewScanDecoder ¶
func NewScanDecoder(frame *Frame, validator Validator) (*ScanDecoder, error)
NewScanDecoder creates a new scan decoder for the given frame.
func (*ScanDecoder) DecodeScan ¶
func (sd *ScanDecoder) DecodeScan(r io.Reader, scan *Scan) error
DecodeScan decodes a single progressive scan. The reader should be positioned at the start of entropy-coded data.
func (*ScanDecoder) GetCoefficientBuffer ¶
func (sd *ScanDecoder) GetCoefficientBuffer() *CoefficientBuffer
GetCoefficientBuffer returns the accumulated coefficient buffer.
func (*ScanDecoder) GetCoefficients ¶
func (sd *ScanDecoder) GetCoefficients() []int
GetCoefficients returns all accumulated DCT coefficients as a flat array. Layout: blocks in raster order, each block contains 64 coefficients.
func (*ScanDecoder) Reset ¶
func (sd *ScanDecoder) Reset()
Reset resets the decoder for a new image.
func (*ScanDecoder) SetHuffmanTable ¶
func (sd *ScanDecoder) SetHuffmanTable(tableClass, tableID int, table *HuffmanTable) error
SetHuffmanTable sets a Huffman table for decoding. tableClass: 0 for DC, 1 for AC tableID: 0-3
type ScanParser ¶
type ScanParser struct {
// contains filtered or unexported fields
}
ScanParser parses progressive JPEG scan markers (SOS).
func NewScanParser ¶
func NewScanParser(validator Validator) *ScanParser
NewScanParser creates a new scan parser with the given validator.
type ScanTracker ¶
type ScanTracker struct {
// ScanCount is the number of scans processed
ScanCount int
}
ScanTracker tracks the number of scans processed to prevent infinite loops. Progressive JPEGs typically have 10-20 scans, so 100 is a generous limit.
func (*ScanTracker) IncrementScan ¶
func (s *ScanTracker) IncrementScan() error
IncrementScan increments the scan counter and checks against the limit. Returns an error if the maximum number of scans has been exceeded.
type Validator ¶
type Validator interface {
// ValidatePrecision validates sample precision (must be 8 or 12).
ValidatePrecision(precision int) error
// ValidateDimensions validates width and height.
ValidateDimensions(width, height int) error
// ValidateSpectralSelection validates Ss and Se parameters.
ValidateSpectralSelection(ss, se int) error
// ValidateSuccessiveApproximation validates Ah and Al parameters.
ValidateSuccessiveApproximation(ah, al int) error
// ValidateComponentCount validates number of components.
ValidateComponentCount(count int) error
// SafeMultiply performs multiplication with overflow checking.
SafeMultiply(a, b int) (int, error)
// SafeAdd performs addition with overflow checking.
SafeAdd(a, b int) (int, error)
// SafeSubtract performs subtraction with underflow checking.
SafeSubtract(a, b int) (int, error)
}
Validator provides validation for progressive JPEG parameters.