jlink

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

Documentation

Overview

Package jlink implements parsing for JPEG Linked Media Format (JLINK) as defined in ISO/IEC 19566-7 (JPEG Systems Part 7).

JLINK provides a standardized way to reference linked media content within JPEG files, allowing images to reference external resources through URIs. This enables features like:

  • Referencing high-resolution versions
  • Linking to related media (audio, video, additional images)
  • Connecting to online resources
  • Creating image collections with shared metadata

JLINK supports various link types:

  • External: Links to resources via HTTP/HTTPS URLs
  • Relative: Links relative to the image location
  • Embedded: Links to content within the same file
  • Fragment: Links to specific parts of referenced content

Reference Types

Different reference relationship types are defined:

  • Alternate: Alternative version of the same content
  • Supplement: Additional/supplementary content
  • Parent: Parent content in a hierarchy
  • Child: Child content in a hierarchy
  • Thumbnail: Thumbnail version of the content

Markers

JLINK content is stored in JUMBF boxes within APP11 marker segments:

  • Marker: 0xFFEB (APP11)
  • JUMBF type UUID identifies JLINK content
  • Payload contains link reference data

Usage Example

data := readJPEGFile("photo.jpg")
parser := jlink.NewParser()
links, err := parser.Parse(data)
if err != nil {
    log.Fatal(err)
}
for _, link := range links {
    fmt.Printf("Link: %s -> %s\n", link.ReferenceType, link.URI)
}

Security Considerations

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

  • MaxLinkedReferences: Maximum number of links (default: 1024)
  • MaxMetadataSize: Maximum total metadata size (default: 64 MB)
  • URI validation to prevent malicious links

References

  • ISO/IEC 19566-7 (JPEG Systems Part 7 - JLINK)

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrInvalidLink indicates the link structure is invalid.
	ErrInvalidLink = errors.New("invalid JLINK reference")

	// ErrInvalidURI indicates the URI is malformed or invalid.
	ErrInvalidURI = errors.New("invalid URI in JLINK reference")

	// ErrReferenceLimitExceeded wraps the security error for reference count.
	ErrReferenceLimitExceeded = security.ErrTooManyReferences

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

	// ErrTruncatedData indicates the link data is truncated.
	ErrTruncatedData = errors.New("truncated JLINK data")

	// ErrNoLinksFound indicates no JLINK references were found.
	ErrNoLinksFound = errors.New("no JLINK references 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")

	// ErrUnsupportedScheme indicates the URI scheme is not supported.
	ErrUnsupportedScheme = errors.New("unsupported URI scheme")

	// ErrUnsafeURI indicates the URI may be unsafe (e.g., file://).
	ErrUnsafeURI = errors.New("potentially unsafe URI")
)

Package-specific errors for JLINK parsing.

View Source
var JLINKBoxType = [4]byte{'j', 'l', 'n', 'k'}

JLINKBoxType is the box type identifier for JLINK content in JUMBF.

View Source
var JLINKUUID = [16]byte{
	0x6A, 0x6C, 0x6E, 0x6B,
	0x00, 0x11, 0x00, 0x10,
	0x80, 0x00, 0x00, 0xAA,
	0x00, 0x38, 0x9B, 0x71,
}

JLINKUUID is the UUID identifying JLINK content type in JUMBF boxes.

This value is the published ISO/IEC 19566-4 Annex A identifier 6A6C6E6B-0011-0010-8000-00AA00389B71 ("jlnk" prefix). It follows the same "[ascii4]-0011-0010-8000-00AA00389B71" shape as the other standards-defined content-type UUIDs catalogued in internal/jpegsystems/jumbf/types.go (JSON, XML, CBOR, ...).

The earlier in-tree value (6A6C696E-6B000000-00110010-800000AA) did not match Annex A and produced bitstreams that a conforming 19566-4 reader would not recognize. Finding R1 of doc/DEFERRED-AUDITS.md §JPEG-Systems.

Functions

func EncodeBinaryLinks(c *LinkCollection) ([]byte, error)

EncodeBinaryLinks encodes a LinkCollection into the ISO/IEC 19566-4 §6.2 binary format. The returned bytes round-trip exactly through ParseBinaryLinks.

numLinks must fit in a single byte (1-255); collections with more than 255 references are rejected with ErrReferenceLimitExceeded so the encoded stream remains strictly 19566-4 conforming.

func ResolveRelativeURI

func ResolveRelativeURI(baseURL, relativeURI string) (string, error)

ResolveRelativeURI resolves a relative URI against a base URL. This is a helper for content retrieval implementations.

Types

type ContentRetriever

type ContentRetriever interface {
	// Retrieve fetches the content at the given URI.
	// Returns the content bytes or an error.
	Retrieve(uri string) ([]byte, error)
}

ContentRetriever is an interface for retrieving linked content. Implementations can provide HTTP, file, or other retrieval methods.

type LinkCollection

type LinkCollection struct {
	// Links contains all parsed link references.
	Links []*LinkReference

	// Version is the JLINK format version.
	Version string

	// FormatVersion is the raw version byte from the binary header
	// (ISO/IEC 19566-4 §6.2). Zero indicates the baseline format.
	FormatVersion uint8

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

LinkCollection represents all JLINK references in an image.

func NewLinkCollection

func NewLinkCollection() *LinkCollection

NewLinkCollection creates a new empty link collection.

func ParseBinaryLinks(data []byte) (*LinkCollection, error)

ParseBinaryLinks parses binary format JLINK data.

Header layout (ISO/IEC 19566-4 §6.2, 4 bytes):

[version:1][numLinks:1][reserved:2]

Each entry: [type:1][refType:1][uriLen:2][uri:uriLen].

The pre-R4 code treated bytes 0-1 as a single big-endian 16-bit link count. For numLinks ≤ 255 the on-wire bytes are identical (version byte is 0), so legacy encoders that relied on the old layout continue to round-trip. Finding R4 of doc/DEFERRED-AUDITS.md §JPEG-Systems.

func (c *LinkCollection) AddLink(link *LinkReference)

AddLink adds a link reference to the collection.

func (*LinkCollection) Count

func (c *LinkCollection) Count() int

Count returns the number of links in the collection.

func (*LinkCollection) FindByType

func (c *LinkCollection) FindByType(refType ReferenceType) []*LinkReference

FindByType returns all links of a specific reference type.

func (c *LinkCollection) FindHTTPLinks() []*LinkReference

FindHTTPLinks returns all HTTP/HTTPS links.

func (c *LinkCollection) FindSafeLinks() []*LinkReference

FindSafeLinks returns all links considered safe.

type LinkReference

type LinkReference struct {
	// LinkType describes how the URI should be interpreted.
	LinkType LinkType

	// ReferenceType describes the relationship to the source image.
	ReferenceType ReferenceType

	// URI is the link target.
	URI string

	// ParsedURI is the parsed URL (nil if URI is invalid or relative).
	ParsedURI *url.URL

	// MediaType is the MIME type of the linked content.
	MediaType *MediaType

	// Label is an optional human-readable label.
	Label string

	// Description is an optional description of the link.
	Description string

	// Width is the width in pixels (for image/video links, 0 if unknown).
	Width int

	// Height is the height in pixels (for image/video links, 0 if unknown).
	Height int

	// FileSize is the size in bytes (0 if unknown).
	FileSize int64

	// Index is the position of this link in the link list.
	Index int
}

LinkReference represents a single JLINK reference entry.

func (*LinkReference) IsHTTP

func (l *LinkReference) IsHTTP() bool

IsHTTP returns true if the link is an HTTP or HTTPS URL.

func (*LinkReference) IsSafe

func (l *LinkReference) IsSafe() bool

IsSafe returns true if the URI is considered safe. Unsafe schemes include file://, javascript:, data: with scripts.

func (*LinkReference) IsValid

func (l *LinkReference) IsValid() bool

IsValid checks if the link reference is valid.

type LinkType

type LinkType uint8

LinkType defines the type of link reference.

const (
	// LinkTypeUnknown indicates an unrecognized link type.
	LinkTypeUnknown LinkType = 0

	// LinkTypeExternal indicates a link to an external resource via URL.
	LinkTypeExternal LinkType = 1

	// LinkTypeRelative indicates a link relative to the image location.
	LinkTypeRelative LinkType = 2

	// LinkTypeEmbedded indicates a link to content within the same file.
	LinkTypeEmbedded LinkType = 3

	// LinkTypeFragment indicates a link to a specific fragment of content.
	LinkTypeFragment LinkType = 4

	// LinkTypeURN indicates a URN-based identifier.
	LinkTypeURN LinkType = 5
)

func (LinkType) IsValid

func (t LinkType) IsValid() bool

IsValid returns true if the link type is recognized.

func (LinkType) String

func (t LinkType) String() string

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

type MediaType

type MediaType struct {
	// Type is the main type (e.g., "image", "video", "audio").
	Type string

	// Subtype is the specific format (e.g., "jpeg", "png", "mp4").
	Subtype string

	// Parameters contains optional parameters (e.g., "charset=utf-8").
	Parameters map[string]string
}

MediaType describes the media type of the linked content.

func ParseMediaType

func ParseMediaType(s string) *MediaType

ParseMediaType parses a MIME type string.

func (*MediaType) String

func (m *MediaType) String() string

String returns the MIME type string.

type NoOpRetriever

type NoOpRetriever struct{}

NoOpRetriever is a ContentRetriever that returns an error for all URIs. Use this as a default when content retrieval is not needed.

func (*NoOpRetriever) Retrieve

func (r *NoOpRetriever) Retrieve(uri string) ([]byte, error)

Retrieve always returns an error indicating retrieval is not supported.

type ParseError

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

	// LinkIndex is the index of the link being parsed.
	LinkIndex int

	// 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, linkIndex int, 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 JLINK references from JUMBF boxes or binary data.

func NewParser

func NewParser() *Parser

NewParser creates a new JLINK parser with default settings.

func NewParserWithLimits

func NewParserWithLimits(maxSize int64, maxRefs int) *Parser

NewParserWithLimits creates a new parser with custom limits.

func (*Parser) Detect

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

Detect checks if the given data contains JLINK references. Returns true if JLINK data is detected, along with the collection.

func (*Parser) ExtractURIs

func (p *Parser) ExtractURIs(data []byte) ([]string, error)

ExtractURIs extracts all URIs from link data without full parsing. Returns a slice of URI strings.

func (*Parser) GetLinkCount

func (p *Parser) GetLinkCount(data []byte) (int, error)

GetLinkCount extracts just the link count from data. This is useful for quick detection without full parsing.

Per ISO/IEC 19566-4 §6.2 the header is one 1-byte version followed by one 1-byte link count (R4); the count lives in data[1].

func (*Parser) Parse

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

Parse parses JLINK references from binary data. Returns the parsed link collection or an error if the data is invalid.

func (*Parser) ParseFromJUMBF

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

ParseFromJUMBF parses JLINK references from a JUMBF box payload. This is the typical entry point when references are extracted from JUMBF.

type ReferenceType

type ReferenceType uint8

ReferenceType defines the relationship type of the reference.

const (
	// RefTypeUnknown indicates an unrecognized reference type.
	RefTypeUnknown ReferenceType = 0

	// RefTypeAlternate indicates an alternative version of the same content.
	RefTypeAlternate ReferenceType = 1

	// RefTypeSupplement indicates supplementary/additional content.
	RefTypeSupplement ReferenceType = 2

	// RefTypeParent indicates a parent in a content hierarchy.
	RefTypeParent ReferenceType = 3

	// RefTypeChild indicates a child in a content hierarchy.
	RefTypeChild ReferenceType = 4

	// RefTypeThumbnail indicates a thumbnail version.
	RefTypeThumbnail ReferenceType = 5

	// RefTypeHighRes indicates a high-resolution version.
	RefTypeHighRes ReferenceType = 6

	// RefTypeLowRes indicates a low-resolution version.
	RefTypeLowRes ReferenceType = 7

	// RefTypeAudio indicates linked audio content.
	RefTypeAudio ReferenceType = 8

	// RefTypeVideo indicates linked video content.
	RefTypeVideo ReferenceType = 9

	// RefTypeMetadata indicates linked metadata.
	RefTypeMetadata ReferenceType = 10

	// RefTypeRelated indicates generally related content.
	RefTypeRelated ReferenceType = 11
)

func (ReferenceType) IsValid

func (r ReferenceType) IsValid() bool

IsValid returns true if the reference type is recognized.

func (ReferenceType) String

func (r ReferenceType) String() string

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

Jump to

Keyboard shortcuts

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