From 6e98469ef723960ce4fcf37b27416cf2ebfca263 Mon Sep 17 00:00:00 2001 From: Přemysl Eric Janouch Date: Thu, 29 Jun 2023 05:01:23 +0200 Subject: WIP: PDF 1.5 cross-reference stream support Perhaps only for Go. --- pdf/pdf.go | 40 +++++++++++++++++++++++++++++++++++++++- test.sh | 3 +-- 2 files changed, 40 insertions(+), 3 deletions(-) diff --git a/pdf/pdf.go b/pdf/pdf.go index 92d18e9..e9f42a7 100644 --- a/pdf/pdf.go +++ b/pdf/pdf.go @@ -671,11 +671,49 @@ func (u *Updater) parse(lex *Lexer, stack *[]Object) (Object, error) { } } +// TODO: ISO 32000-2:2020 7.5.8.2 Cross-reference stream dictionary +// - How to update this kind of file? Hybrid-reference file? +// ⋄ XRefStm could point to this old-new xref. But it's actually a /Prev. +func (u *Updater) loadXrefStream( + lex *Lexer, loadedEntries map[uint]struct{}) error { + var stack []Object + for { + object, err := u.parse(lex, &stack) + if err != nil { + return fmt.Errorf("invalid xref table: %s", err) + } else if object.Kind == End { + return errors.New("invalid xref table") + } + + // For the sake of simplicity, keep stacking until we find an object. + if object.Kind != Indirect { + stack = append(stack, object) + continue + } + + object = object.Array[0] + if object.Kind != Stream { + return errors.New("invalid xref table") + } + if typ, ok := object.Dict["Type"]; !ok || typ.String != "XRef" { + return errors.New("invalid xref stream") + } + if filter, ok := object.Dict["Filter"]; !ok || + filter.String != "FlateDecode" { + return errors.New("invalid xref stream") + } + + return errors.New("unimplemented") + } +} + +// TODO: Also return the trailer dictionary, but remove any XRef/stream fields, +// perhaps as per Table 17 + /Filter, /Length. func (u *Updater) loadXref(lex *Lexer, loadedEntries map[uint]struct{}) error { var throwawayStack []Object if keyword, _ := u.parse(lex, &throwawayStack); keyword.Kind != Keyword || keyword.String != "xref" { - return errors.New("invalid xref table") + return u.loadXrefStream(lex, loadedEntries) } for { object, _ := u.parse(lex, &throwawayStack) diff --git a/test.sh b/test.sh index 831a15e..9d3ab60 100755 --- a/test.sh +++ b/test.sh @@ -11,8 +11,7 @@ mkdir tmp # Create documents in various tools log "Creating source documents" -inkscape --pipe --export-filename=tmp/cairo.pdf --export-pdf-version=1.4 \ -<<'EOF' 2>/dev/null || : +inkscape --pipe --export-filename=tmp/cairo.pdf <<'EOF' 2>/dev/null || : Hello EOF -- cgit v1.2.3-70-g09d2