internal/

directory
v1.0.1 Latest Latest
Warning

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

Go to latest
Published: Jun 30, 2026 License: MIT

README

Internal Packages - Developer Guide

Version: 1.0.0 Last Updated: 2025-12-20

This document provides guidelines for developing internal packages within the JPEG library. All internal packages should follow these conventions to maintain consistency across the codebase.

Logging Infrastructure

The JPEG library uses structured logging via the github.com/0verkilll/logger package. All internal packages MUST use the logging patterns described here.

Log Levels

Use the appropriate log level based on the type of information:

Level Function When to Use
Debug logger.Debug() Detailed technical information for debugging. Use for marker offsets, coefficient values, parsing steps.
Info logger.Info() Significant events in normal operation. Use for format detection, decode start/completion.
Warn logger.Warn() Potentially problematic situations. Use for deprecated features, fallback behaviors, recoverable errors.
Error logger.Error() Error conditions that don't halt execution. Use for malformed data that can be skipped, optional feature failures.
Import Pattern for Internal Packages

All internal packages should import the logger package directly:

import (
    "github.com/0verkilll/logger"
)
Structured Logging Keys

Use consistent key names across all packages:

Key Type Description
"offset" int Byte offset in the data stream
"marker" string/int JPEG marker type (e.g., "SOF0", 0xC0)
"format" string File format being processed
"width" int Image width in pixels
"height" int Image height in pixels
"component" int Component index (0=Y, 1=Cb, 2=Cr)
"block" int Block index in scan order
"value" int/float Decoded or computed value
"error" error Error object for context
"size" int Size in bytes
"table" int Table index (Huffman, quantization)
Example Code Snippets
Debug Logging - Marker Parsing
func (d *Decoder) parseMarker(offset int, markerType byte) {
    logger.Debug("parsing marker",
        "offset", offset,
        "marker", fmt.Sprintf("0x%02X", markerType),
        "format", "JPEG",
    )
    // ... parsing logic
}
Info Logging - Decode Start/Complete
func (d *Decoder) Decode() ([]int, error) {
    logger.Info("starting decode",
        "format", d.formatName,
        "width", d.width,
        "height", d.height,
    )

    // ... decode logic

    logger.Info("decode complete",
        "format", d.formatName,
        "coefficients", len(result),
    )
    return result, nil
}
Warn Logging - Fallback Behavior
func (d *Decoder) processBlock(blockIdx int) {
    if d.quantTable == nil {
        logger.Warn("missing quantization table, using default",
            "block", blockIdx,
            "table", d.quantTableID,
        )
        d.quantTable = defaultQuantTable
    }
    // ... block processing
}
Error Logging - Recoverable Error
func (d *Decoder) decodeCoefficient(k int) (int, error) {
    value, err := d.readValue()
    if err != nil {
        logger.Error("failed to decode coefficient, using zero",
            "block", d.currentBlock,
            "coefficient", k,
            "error", err,
        )
        return 0, nil // Recoverable - continue with zero
    }
    return value, nil
}
NopLogger for Zero Overhead

When no logger is configured (the default), all logging calls are no-ops with zero allocations. The library uses NopLogger which immediately returns without processing arguments:

// NopLogger has zero overhead - safe for hot paths
type NopLogger struct{}

func (l *NopLogger) Debug(_ string, _ ...any) {}
func (l *NopLogger) Info(_ string, _ ...any) {}
func (l *NopLogger) Warn(_ string, _ ...any) {}
func (l *NopLogger) Error(_ string, _ ...any) {}
Testing with Logging

In tests, you can capture log output for verification:

func TestDecoderLogging(t *testing.T) {
    // Set up a test logger that captures output
    var buf bytes.Buffer
    testLogger := logger.NewLogger(
        logger.WithWriter(&buf),
        logger.WithLevel(logger.LevelDebug),
    )
    logger.SetLogger(testLogger)
    defer logger.SetLogger(nil)

    // Run decode
    decoder := NewDecoder(testData)
    _, _ = decoder.Decode()

    // Verify log output
    output := buf.String()
    if !strings.Contains(output, "parsing marker") {
        t.Error("expected marker parsing to be logged")
    }
}

Internationalization (i18n)

All user-facing error messages MUST use the translation system.

Import Pattern
import (
    "github.com/0verkilll/i18n"
)
Error Message Pattern
// Define a translate helper in each package
func translate(key string, args ...any) string {
    return i18n.T(key, args...)
}

// Use in error creation
func (d *Decoder) validateHeader() error {
    if d.width == 0 {
        return fmt.Errorf(translate("jpeg.error.invalid_width"))
    }
    return nil
}
Translation Key Convention

All keys should follow this naming pattern:

jpeg.<package>.<category>.<specific>

Examples:

  • jpeg.huffman.error.invalid_table
  • jpeg.jpegls.decode.start
  • jpeg.jpeg2000.wavelet.level

Security Requirements

Safe Integer Conversions

All internal packages MUST use the internal/safeconv package for integer conversions:

import "github.com/0verkilll/jpeg/internal/safeconv"

func (d *Decoder) allocateBuffer(size int64) ([]byte, error) {
    bufSize, err := safeconv.Int64ToInt(size)
    if err != nil {
        return nil, fmt.Errorf("buffer size overflow: %w", err)
    }
    return make([]byte, bufSize), nil
}
Buffer Size Validation

Always validate buffer sizes against security limits before allocation:

const maxBufferSize = 536870912 // 512MB

func (d *Decoder) decode() error {
    bufferSize := int64(d.width) * int64(d.height) * int64(d.components)
    if bufferSize > maxBufferSize {
        return fmt.Errorf("buffer size %d exceeds maximum %d", bufferSize, maxBufferSize)
    }
    // ... allocate and use buffer
}

Package Structure

Each internal package should follow this structure:

internal/<package>/
    doc.go        # Package documentation
    types.go      # Type definitions and constants
    errors.go     # Package-specific errors
    decoder.go    # Main decoder implementation
    encoder.go    # Main encoder implementation (if applicable)
    *_test.go     # Unit tests
    fuzz_test.go  # Fuzz tests (required for all decoders)

Testing Requirements

Unit Tests
  • Each package MUST have unit tests with at least 80% coverage
  • Use table-driven tests for multiple scenarios
  • Test error paths, not just happy paths
Fuzz Tests

All decoder packages MUST include fuzz tests:

func FuzzDecode(f *testing.F) {
    // Add seed corpus
    f.Add([]byte{0xFF, 0xD8, 0xFF, 0xE0})

    f.Fuzz(func(t *testing.T, data []byte) {
        d := NewDecoder(data)
        _, _ = d.Decode() // Must not panic
    })
}

These guidelines ensure consistent, maintainable, and secure code across all internal packages.

Directories

Path Synopsis
Package jpeg2000 provides JPEG 2000 encoding and decoding support.
Package jpeg2000 provides JPEG 2000 encoding and decoding support.
htj2k
Package htj2k implements HTJ2K block decoding.
Package htj2k implements HTJ2K block decoding.
jp2
jp3d
Package jp3d implements JPEG 2000 Part 10 (JP3D) volumetric image support as specified in ISO/IEC 15444-10.
Package jp3d implements JPEG 2000 Part 10 (JP3D) volumetric image support as specified in ISO/IEC 15444-10.
jpip
Package jpip implements JPEG 2000 Part 9 (JPIP) client response parsing as specified in ISO/IEC 15444-9.
Package jpip implements JPEG 2000 Part 9 (JPIP) client response parsing as specified in ISO/IEC 15444-9.
jpm
Package jpm provides JPEG 2000 Part 6 (JPM) compound image support per ISO/IEC 15444-6.
Package jpm provides JPEG 2000 Part 6 (JPM) compound image support per ISO/IEC 15444-6.
jpsec
Package jpsec implements JPEG 2000 Part 8 (JPSEC) security features as specified in ISO/IEC 15444-8.
Package jpsec implements JPEG 2000 Part 8 (JPSEC) security features as specified in ISO/IEC 15444-8.
jpwl
Package jpwl implements JPEG 2000 Part 11 (JPWL) wireless transmission support as specified in ISO/IEC 15444-11.
Package jpwl implements JPEG 2000 Part 11 (JPWL) wireless transmission support as specified in ISO/IEC 15444-11.
jpx
Package jpx provides JPEG 2000 Part 2 (JPX) extended file format support.
Package jpx provides JPEG 2000 Part 2 (JPX) extended file format support.
mct
Package mct implements the Multi-Component Transform (MCT) defined by ISO/IEC 15444-1 §F.4.9 for JPEG 2000.
Package mct implements the Multi-Component Transform (MCT) defined by ISO/IEC 15444-1 §F.4.9 for JPEG 2000.
mj2
Package mj2 implements Motion JPEG 2000 (MJ2/MJP2) per ISO/IEC 15444-3.
Package mj2 implements Motion JPEG 2000 (MJ2/MJP2) per ISO/IEC 15444-3.
mq
security
Package security provides security validation for JPEG 2000 parsing
Package security provides security validation for JPEG 2000 parsing
trellis
Package trellis implements trellis quantization for JPEG 2000 Part 2 (JPX).
Package trellis implements trellis quantization for JPEG 2000 Part 2 (JPX).
Package jpegai provides parsing and decoding support for JPEG AI (ISO/IEC 6046) neural network-based image compression.
Package jpegai provides parsing and decoding support for JPEG AI (ISO/IEC 6046) neural network-based image compression.
Package jpegls implements JPEG-LS encoding and decoding per ITU-T T.87/ISO 14495-1 with T.870 extensions for higher bit depths.
Package jpegls implements JPEG-LS encoding and decoding per ITU-T T.87/ISO 14495-1 with T.870 extensions for higher bit depths.
Package jpegpleno provides decoding support for JPEG Pleno.
Package jpegpleno provides decoding support for JPEG Pleno.
holography
Package holography provides decoding support for JPEG Pleno Holography.
Package holography provides decoding support for JPEG Pleno Holography.
lightfield
Package lightfield provides types and decoding for JPEG Pleno Light Field.
Package lightfield provides types and decoding for JPEG Pleno Light Field.
pointcloud
Package pointcloud provides types and decoding for JPEG Pleno Point Cloud.
Package pointcloud provides types and decoding for JPEG Pleno Point Cloud.
jpegsystems
jlink
Package jlink implements parsing for JPEG Linked Media Format (JLINK) as defined in ISO/IEC 19566-7 (JPEG Systems Part 7).
Package jlink implements parsing for JPEG Linked Media Format (JLINK) as defined in ISO/IEC 19566-7 (JPEG Systems Part 7).
jpeg360
Package jpeg360 implements parsing for JPEG 360 panoramic image metadata as defined in ISO/IEC 19566-6 (JPEG Systems Part 6).
Package jpeg360 implements parsing for JPEG 360 panoramic image metadata as defined in ISO/IEC 19566-6 (JPEG Systems Part 6).
jumbf
Package jumbf implements parsing for JPEG Universal Metadata Box Format (JUMBF) as defined in ISO/IEC 19566-5 (JPEG Systems Part 5).
Package jumbf implements parsing for JPEG Universal Metadata Box Format (JUMBF) as defined in ISO/IEC 19566-5 (JPEG Systems Part 5).
Package jpegtrust implements parsing and validation for JPEG Trust metadata as defined in ISO/IEC 21617 (JPEG Trust).
Package jpegtrust implements parsing and validation for JPEG Trust metadata as defined in ISO/IEC 21617 (JPEG Trust).
Package jpegxe provides JPEG XE (ISO/IEC 21122-5) decoding support for event camera data.
Package jpegxe provides JPEG XE (ISO/IEC 21122-5) decoding support for event camera data.
Package jpegxs provides JPEG XS (ISO/IEC 21122) codestream decoding.
Package jpegxs provides JPEG XS (ISO/IEC 21122) codestream decoding.
container
Package container provides JPEG XS (ISO/IEC 21122-3) transport format parsing.
Package container provides JPEG XS (ISO/IEC 21122-3) transport format parsing.
Package jpegxt provides JPEG XT (ISO/IEC 18477) HDR extension support.
Package jpegxt provides JPEG XT (ISO/IEC 18477) HDR extension support.
Package logging provides logging helper functions for internal packages.
Package logging provides logging helper functions for internal packages.
Package safeconv provides safe integer type conversions with overflow detection.
Package safeconv provides safe integer type conversions with overflow detection.

Jump to

Keyboard shortcuts

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