Documentation
¶
Overview ¶
Package objects defines the PDF object model this repository owns, plus the Store interface for reading it out of a file.
The object model is deliberately re-declared here rather than borrowed from whichever library currently parses the file. That library is an implementation detail behind Store; if it is replaced, adapters change and callers do not. The cost is one translation layer in each adapter, paid once.
The model follows ISO 32000-2 §7.3: eight basic object types, plus streams and indirect references.
Index ¶
- Variables
- func AsNum(o Object) (float64, bool)
- func DecodeTextString(o Object) string
- func GetBool(s Store, d Dict, key Name) (bool, bool)
- func GetInt(s Store, d Dict, key Name) (int64, bool)
- func GetNum(s Store, d Dict, key Name) (float64, bool)
- func GetStreamData(s Store, d Dict, key Name) ([]byte, bool)
- type Array
- type Bool
- type Dict
- type Int
- type Name
- type Null
- type Object
- type Real
- type Ref
- type Store
- type Stream
- type String
Constants ¶
This section is empty.
Variables ¶
var ErrNotFound = errors.New("objects: not found")
ErrNotFound is returned when a referenced object is absent. A malformed PDF with dangling references is common enough that this is an expected outcome, not an exceptional one.
Functions ¶
func DecodeTextString ¶
DecodeTextString converts a PDF text string to a Go string per ISO 32000-2 §7.9.2.1: UTF-16BE when the byte-order mark is present, PDFDocEncoded otherwise.
This lives here rather than in a caller because PDF text strings appear all over the format -- /Lang, /Title, /ActualText, outline titles, form field values -- and every one of them needs the same BOM check. Skipping it yields text with an interleaved NUL between every character.
Only the Latin range of PDFDocEncoding is handled, where it agrees with Unicode. Positions 0x80-0x9F differ, but text strings in practice do not use them.
func GetInt ¶
GetInt resolves d[key] as an integer. A Real is accepted and truncated: producers write integers as reals often enough that rejecting them loses real data for no benefit.
func GetStreamData ¶
GetStreamData resolves d[key] as a stream and returns its decoded bytes.
This is the form nearly every caller wants, and it exists because the two-step version has a silent failure mode: a stream fetched with GetStream has Decoded nil until someone calls Decode, so reading it directly yields nothing and looks like an empty stream rather than an un-decoded one.
A decode failure reports false rather than an error, matching the other getters: a stream this package cannot decode is usually an image codec, which is a routine outcome and not the caller's problem to distinguish here.
Types ¶
type Array ¶
type Array []Object
Array is a PDF array.
func ArrayOrSingle ¶
ArrayOrSingle normalizes a value that the specification allows to be either a single object or an array of them, which PDF does in many places (/Contents, /Filter, /Annots).
type Name ¶
type Name string
Name is a PDF name, stored without the leading slash and with #xx escapes already resolved.
type Object ¶
type Object interface {
// contains filtered or unexported methods
}
Object is any PDF object. The set is closed: only the types in this package implement it.
type Store ¶
type Store interface {
// Resolve follows indirect references until it reaches a direct object.
// A non-Ref argument is returned unchanged. A dangling reference resolves
// to Null rather than an error, matching the PDF rule that a reference to a
// nonexistent object is null.
Resolve(Object) (Object, error)
// Trailer returns the trailer dictionary.
Trailer() (Dict, error)
// Catalog returns the document catalog, /Root.
Catalog() (Dict, error)
// PageCount returns the number of pages.
PageCount() int
// Page returns the page dictionary for a 1-based page number, with
// inheritable attributes (/Resources, /MediaBox, /CropBox, /Rotate) already
// resolved from ancestors per ISO 32000-2 §7.7.3.4.
Page(n int) (Dict, error)
// PageContent returns the concatenated, decoded content streams of a 1-based
// page. A page's /Contents may be an array of streams that must be joined
// with intervening whitespace before tokenizing, which this handles.
PageContent(n int) ([]byte, error)
// Decode applies a stream's filter chain, populating its Decoded field.
//
// Required on the interface rather than left to the adapter because most
// streams worth reading are not page content: a /ToUnicode CMap, an embedded
// CMap, a font program, an embedded file. Resolve returns those with Decoded
// nil, since decoding every stream a caller merely looked at would decompress
// the whole document.
//
// A stream whose final filter is an image codec is left alone and reports no
// error: its output is pixels rather than bytes, and callers that want the
// original JPEG or CCITT data want Raw. Decoded staying nil is the signal to
// use Raw.
Decode(*Stream) error
// Version reports the PDF version, preferring the catalog's /Version over
// the header when both are present, per ISO 32000-2 §7.5.5.
Version() string
// Encrypted reports whether the file has an /Encrypt dictionary. A file may
// be readable and still report true: empty-password encryption is common.
Encrypted() bool
// Close releases any resources held.
io.Closer
}
Store gives read access to a PDF's object graph.
It is declared here, by the packages that consume it, and implemented by adapters in subdirectories. Every method may hit the file, so an implementation is not required to be safe for concurrent use unless it says so; page-level parallelism uses one Store per worker or an explicitly concurrent implementation.
type Stream ¶
type Stream struct {
Dict Dict
Raw []byte
Decoded []byte
// Filters is the filter chain in application order, as named in /Filter.
Filters []Name
}
Stream is a PDF stream: a dictionary plus data.
Raw holds bytes exactly as they appear in the file, still encoded by Filters. Decoded holds the result of applying the filter chain, and is nil until a decode is attempted.
Both are kept because the distinction is load-bearing. Image extraction wants Raw so a JPEG can be written out in its original encoding without a re-encode; content-stream interpretation wants Decoded.