jpeg360

package
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 Imports: 6 Imported by: 0

Documentation

Overview

Package jpeg360 implements parsing for JPEG 360 panoramic image metadata as defined in ISO/IEC 19566-6 (JPEG Systems Part 6).

JPEG 360 provides standardized metadata for 360-degree panoramic images, including projection type information, initial viewport parameters, and coverage angles. This metadata is stored within JUMBF boxes embedded in APP11 marker segments.

Projection Types

The package supports the following projection types:

  • Equirectangular: Standard 360 spherical projection (most common)
  • Cubemap: Six-face cube projection
  • Cylindrical: Cylindrical projection for partial panoramas
  • Rectilinear: Flat rectilinear projection for narrow FOV

Metadata Structure

JPEG 360 metadata is stored in a JUMBF box with specific UUID:

  • Box Type: 'jumb' (JUMBF superbox)
  • Content Type UUID: Identifies as JPEG 360 metadata
  • Payload: XML or binary parameters defining projection and viewport

Usage Example

data := readJPEGFile("panorama.jpg")
parser := jpeg360.NewParser()
metadata, err := parser.Parse(data)
if err != nil {
    log.Fatal(err)
}
fmt.Printf("Projection: %s, FOV: %.1f degrees\n",
    metadata.ProjectionType, metadata.InitialViewport.FOV)

Security Considerations

The parser enforces security limits from security/limits.go:

  • MaxMetadataSize: Maximum metadata size (default: 64 MB)
  • Field value validation for angles and coordinates

References

  • ISO/IEC 19566-6 (JPEG Systems Part 6 - JPEG 360)
  • Spherical Video V2 Metadata Spec (for compatibility)

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrInvalidMetadata indicates the 360 metadata structure is invalid.
	ErrInvalidMetadata = errors.New("invalid JPEG 360 metadata")

	// ErrInvalidProjection indicates the projection type is invalid or unsupported.
	ErrInvalidProjection = errors.New("invalid projection type")

	// ErrInvalidViewport indicates the viewport parameters are invalid.
	ErrInvalidViewport = errors.New("invalid viewport parameters")

	// ErrMetadataTooLarge wraps the security error for metadata size.
	ErrMetadataTooLarge = security.ErrMetadataTooLarge

	// ErrTruncatedData indicates the metadata is truncated.
	ErrTruncatedData = errors.New("truncated JPEG 360 metadata")

	// ErrNoMetadataFound indicates no JPEG 360 metadata was found.
	ErrNoMetadataFound = errors.New("no JPEG 360 metadata found")

	// ErrNilData indicates nil input data was provided.
	ErrNilData = errors.New("nil data provided")

	// ErrEmptyData indicates empty input data was provided.
	ErrEmptyData = errors.New("empty data provided")

	// ErrInvalidAngle indicates an angle value is out of valid range.
	ErrInvalidAngle = errors.New("invalid angle value")

	// ErrInvalidCoverage indicates coverage values are invalid.
	ErrInvalidCoverage = errors.New("invalid coverage values")
)

Package-specific errors for JPEG 360 parsing.

View Source
var JPEG360BoxType = [4]byte{'j', 'p', '3', '6'}

JPEG360BoxType is the box type identifier for JPEG 360 content in JUMBF.

View Source
var JPEG360UUID = [16]byte{
	0x6a, 0x70, 0x65, 0x67,
	0x33, 0x36, 0x30, 0x00,
	0x00, 0x11, 0x00, 0x10,
	0x80, 0x00, 0x00, 0xaa,
}

JPEG360UUID is the UUID identifying JPEG 360 content type. Per ISO/IEC 19566-6.

Functions

func EncodeBinaryMetadata

func EncodeBinaryMetadata(m *Metadata360) ([]byte, error)

EncodeBinaryMetadata encodes a Metadata360 into the ISO/IEC 19566-6 binary subset. Viewport and coverage floats are emitted as little-endian float32 matching ParseBinaryMetadata.

The output is always 32 bytes:

[projection:1][stereo:1][reserved:2][viewport:16][coverage:24 (2*f32 + 16 reserved)]

Types

type Coverage

type Coverage struct {
	// HorizontalFOV is the horizontal field of view in degrees (0-360).
	HorizontalFOV float64

	// VerticalFOV is the vertical field of view in degrees (0-180).
	VerticalFOV float64

	// LeftCoverage is the left edge angle in degrees from center.
	LeftCoverage float64

	// RightCoverage is the right edge angle in degrees from center.
	RightCoverage float64

	// TopCoverage is the top edge angle in degrees from horizon.
	TopCoverage float64

	// BottomCoverage is the bottom edge angle in degrees from horizon.
	BottomCoverage float64
}

Coverage represents the angular coverage of the panoramic image.

func (*Coverage) IsFullSphere

func (c *Coverage) IsFullSphere() bool

IsFullSphere returns true if the coverage represents a complete 360x180 sphere.

func (*Coverage) IsValid

func (c *Coverage) IsValid() bool

IsValid checks if the coverage values are within valid ranges.

type CubemapLayout

type CubemapLayout uint8

CubemapLayout defines the layout of faces in a cubemap projection.

const (
	// CubemapLayoutStandard is the 3x2 grid layout (width = 3 * face, height = 2 * face).
	// Order: +X, -X, +Y, -Y, +Z, -Z (or Right, Left, Top, Bottom, Front, Back).
	CubemapLayoutStandard CubemapLayout = 0

	// CubemapLayoutStrip is a 6x1 horizontal strip.
	CubemapLayoutStrip CubemapLayout = 1

	// CubemapLayoutCross is a cross/T-shape layout.
	CubemapLayoutCross CubemapLayout = 2
)

func (CubemapLayout) String

func (l CubemapLayout) String() string

String returns a human-readable name for the cubemap layout.

type Metadata360

type Metadata360 struct {
	// ProjectionType defines how the sphere is projected to 2D.
	ProjectionType ProjectionType

	// InitialViewport specifies the default view when the image is first displayed.
	InitialViewport Viewport

	// Coverage specifies the angular coverage of the panoramic content.
	Coverage Coverage

	// CubemapLayout specifies the face layout (only valid for cubemap projection).
	CubemapLayout CubemapLayout

	// Stereo indicates if this is a stereoscopic 360 image.
	Stereo bool

	// StereoMode specifies the stereo arrangement (if Stereo is true).
	// Common values: "mono", "left-right", "top-bottom".
	StereoMode string

	// SourceWidth is the original image width in pixels.
	SourceWidth int

	// SourceHeight is the original image height in pixels.
	SourceHeight int

	// Version is the metadata format version.
	Version string

	// RawData contains the original raw metadata bytes.
	RawData []byte
}

Metadata360 represents the complete JPEG 360 metadata for a panoramic image.

func NewMetadata360

func NewMetadata360() *Metadata360

NewMetadata360 creates a new Metadata360 with default values.

func ParseBinaryMetadata

func ParseBinaryMetadata(data []byte) (*Metadata360, error)

ParseBinaryMetadata parses binary format JPEG 360 metadata.

Layout (ISO/IEC 19566-6 binary subset, Appendix):

[projection:1][stereo:1][reserved:2][viewport:16][coverage:24]

Viewport is four float32 values (yaw, pitch, roll, FOV) and coverage contains two float32 values (hFOV, vFOV) followed by four reserved bytes. Per 19566-6 the float32 fields are encoded little-endian; previous versions of this file used big-endian which did not match any conforming producer. Finding R2 of doc/DEFERRED-AUDITS.md §JPEG-Systems.

func (*Metadata360) IsValid

func (m *Metadata360) IsValid() bool

IsValid checks if the metadata is valid.

type ParseError

type ParseError struct {
	// Offset is the byte position where the error occurred.
	Offset int64

	// Field is the field being parsed when the error occurred.
	Field string

	// Message describes the error.
	Message string

	// Cause is the underlying error.
	Cause error
}

ParseError provides detailed context for parsing errors.

func NewParseError

func NewParseError(offset int64, field, message string, cause error) *ParseError

NewParseError creates a new ParseError with the given details.

func (*ParseError) Error

func (e *ParseError) Error() string

Error implements the error interface.

func (*ParseError) Unwrap

func (e *ParseError) Unwrap() error

Unwrap returns the underlying error.

type Parser

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

Parser parses JPEG 360 metadata from JUMBF boxes or binary data.

func NewParser

func NewParser() *Parser

NewParser creates a new JPEG 360 metadata parser with default settings.

func NewParserWithLimit

func NewParserWithLimit(maxSize int64) *Parser

NewParserWithLimit creates a new parser with a custom metadata size limit.

func (*Parser) Detect

func (p *Parser) Detect(data []byte) (bool, *Metadata360, error)

Detect checks if the given data contains JPEG 360 metadata. Returns true if JPEG 360 metadata is detected, along with the metadata.

func (*Parser) ExtractViewport

func (p *Parser) ExtractViewport(data []byte) (*Viewport, error)

ExtractViewport extracts viewport parameters from metadata. Returns the viewport or default values if not present.

func (*Parser) GetProjectionType

func (p *Parser) GetProjectionType(data []byte) (ProjectionType, error)

GetProjectionType extracts just the projection type from metadata. This is useful for quick detection without full parsing.

func (*Parser) Parse

func (p *Parser) Parse(data []byte) (*Metadata360, error)

Parse parses JPEG 360 metadata from binary data. Returns the parsed metadata or an error if the data is invalid.

func (*Parser) ParseFromJUMBF

func (p *Parser) ParseFromJUMBF(payload []byte) (*Metadata360, error)

ParseFromJUMBF parses JPEG 360 metadata from a JUMBF box payload. This is the typical entry point when metadata is extracted from JUMBF.

type ProjectionType

type ProjectionType uint8

ProjectionType defines the type of spherical/panoramic projection.

const (
	// ProjectionUnknown indicates an unrecognized or invalid projection.
	ProjectionUnknown ProjectionType = 0

	// ProjectionEquirectangular is the standard 360 spherical projection.
	// Maps the entire sphere to a 2:1 aspect ratio rectangular image.
	// This is the most common format for 360 photos and videos.
	ProjectionEquirectangular ProjectionType = 1

	// ProjectionCubemap is a six-face cube projection.
	// The sphere is projected onto six square faces (front, back, left, right, top, bottom).
	ProjectionCubemap ProjectionType = 2

	// ProjectionCylindrical is a cylindrical projection.
	// Used for partial panoramas that don't cover the full sphere vertically.
	ProjectionCylindrical ProjectionType = 3

	// ProjectionRectilinear is a flat rectilinear projection.
	// Used for narrow field-of-view images extracted from 360 content.
	ProjectionRectilinear ProjectionType = 4

	// ProjectionFisheye is a fisheye lens projection.
	// Captures a hemispherical or near-hemispherical field of view.
	ProjectionFisheye ProjectionType = 5

	// ProjectionEAC is the Equi-Angular Cubemap projection.
	// An improved cubemap with more uniform sampling across faces.
	ProjectionEAC ProjectionType = 6
)

func (ProjectionType) IsValid

func (p ProjectionType) IsValid() bool

IsValid returns true if the projection type is recognized.

func (ProjectionType) String

func (p ProjectionType) String() string

String returns a human-readable name for the projection type.

type Viewport

type Viewport struct {
	// Yaw is the horizontal rotation in degrees (-180 to 180).
	// 0 = center, positive = right, negative = left.
	Yaw float64

	// Pitch is the vertical rotation in degrees (-90 to 90).
	// 0 = horizon, positive = up, negative = down.
	Pitch float64

	// Roll is the rotation around the view axis in degrees (-180 to 180).
	Roll float64

	// FOV is the field of view in degrees (typically 30-180).
	// Represents the horizontal field of view for the initial view.
	FOV float64
}

Viewport represents the initial view parameters for a 360 image.

func (*Viewport) IsValid

func (v *Viewport) IsValid() bool

IsValid checks if the viewport parameters are within valid ranges.

Jump to

Keyboard shortcuts

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