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
Link Types ¶
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 ¶
- Variables
- func EncodeBinaryLinks(c *LinkCollection) ([]byte, error)
- func ResolveRelativeURI(baseURL, relativeURI string) (string, error)
- type ContentRetriever
- type LinkCollection
- type LinkReference
- type LinkType
- type MediaType
- type NoOpRetriever
- type ParseError
- type Parser
- func (p *Parser) Detect(data []byte) (bool, *LinkCollection, error)
- func (p *Parser) ExtractURIs(data []byte) ([]string, error)
- func (p *Parser) GetLinkCount(data []byte) (int, error)
- func (p *Parser) Parse(data []byte) (*LinkCollection, error)
- func (p *Parser) ParseFromJUMBF(payload []byte) (*LinkCollection, error)
- type ReferenceType
Constants ¶
This section is empty.
Variables ¶
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.
var JLINKBoxType = [4]byte{'j', 'l', 'n', 'k'}
JLINKBoxType is the box type identifier for JLINK content in JUMBF.
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 ¶
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 ¶
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 ¶
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 (*LinkCollection) AddLink ¶
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 (*LinkCollection) FindHTTPLinks ¶
func (c *LinkCollection) FindHTTPLinks() []*LinkReference
FindHTTPLinks returns all HTTP/HTTPS links.
func (*LinkCollection) FindSafeLinks ¶
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 )
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 ¶
ParseMediaType parses a 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.
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 ¶
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 ¶
ExtractURIs extracts all URIs from link data without full parsing. Returns a slice of URI strings.
func (*Parser) GetLinkCount ¶
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.