Skip to content

Commit

Permalink
Fix #794 , add PDF 2.0 disclaimer
Browse files Browse the repository at this point in the history
  • Loading branch information
hhrutter committed Feb 16, 2024
1 parent 032b32d commit 694f81f
Show file tree
Hide file tree
Showing 19 changed files with 169 additions and 124 deletions.
36 changes: 32 additions & 4 deletions pkg/api/api.go
Expand Up @@ -47,6 +47,25 @@ import (
"github.com/pkg/errors"
)

func logDisclaimerPDF20() {
disclaimer := `
***************************** Disclaimer ****************************
* PDF 2.0 features are supported on a need basis. *
* (See ISO 32000:2 6.3.2 Conformance of PDF processors) *
* At the moment pdfcpu comes with basic PDF 2.0 support. *
* Please let us know which feature you would like to see supported, *
* provide a sample PDF file and create an issue: *
* https://github.com/pdfcpu/pdfcpu/issues/new/choose *
*********************************************************************`

if log.ValidateEnabled() {
log.Validate.Println(disclaimer)
}
if log.CLIEnabled() {
log.CLI.Println(disclaimer)
}
}

// ReadContext uses an io.ReadSeeker to build an internal structure holding its cross reference table aka the Context.
func ReadContext(rs io.ReadSeeker, conf *model.Configuration) (*model.Context, error) {
if rs == nil {
Expand All @@ -68,6 +87,10 @@ func ReadContextFile(inFile string) (*model.Context, error) {
return nil, err
}

if ctx.Version() == model.V20 {
logDisclaimerPDF20()
}

if err = validate.XRefTable(ctx.XRefTable); err != nil {
return nil, err
}
Expand All @@ -77,6 +100,11 @@ func ReadContextFile(inFile string) (*model.Context, error) {

// ValidateContext validates ctx.
func ValidateContext(ctx *model.Context) error {

if ctx.Version() == model.V20 {
logDisclaimerPDF20()
}

return validate.XRefTable(ctx.XRefTable)
}

Expand Down Expand Up @@ -130,6 +158,10 @@ func readAndValidate(rs io.ReadSeeker, conf *model.Configuration, from1 time.Tim

from2 := time.Now()

if ctx.Version() == model.V20 {
logDisclaimerPDF20()
}

if err = validate.XRefTable(ctx.XRefTable); err != nil {
return nil, 0, 0, err
}
Expand All @@ -146,10 +178,6 @@ func ReadValidateAndOptimize(rs io.ReadSeeker, conf *model.Configuration, from1
return nil, 0, 0, 0, err
}

if ctx.Version() == model.V20 {
return nil, 0, 0, 0, pdfcpu.ErrUnsupportedVersion
}

from3 := time.Now()
if err = OptimizeContext(ctx); err != nil {
return nil, 0, 0, 0, err
Expand Down
4 changes: 0 additions & 4 deletions pkg/api/booklet.go
Expand Up @@ -88,10 +88,6 @@ func Booklet(rs io.ReadSeeker, w io.Writer, imgFiles, selectedPages []string, nu
return err
}

if ctx.Version() == model.V20 {
return pdfcpu.ErrUnsupportedVersion
}

if err := ctx.EnsurePageCount(); err != nil {
return err
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/api/extract.go
Expand Up @@ -264,7 +264,7 @@ func ExtractPages(rs io.ReadSeeker, outDir, fileName string, selectedPages []str

if len(pages) == 0 {
if log.CLIEnabled() {
log.CLI.Println("aborted: nothing to extract!")
log.CLI.Println("aborted: missing page numbers!")
}
return nil
}
Expand Down
10 changes: 5 additions & 5 deletions pkg/api/merge.go
Expand Up @@ -36,7 +36,7 @@ func appendTo(rs io.ReadSeeker, fName string, ctxDest *model.Context, dividerPag
return err
}

if ctxSource.Version() == model.V20 {
if ctxDest.Version() < model.V20 && ctxSource.Version() == model.V20 {
return pdfcpu.ErrUnsupportedVersion
}

Expand Down Expand Up @@ -93,7 +93,9 @@ func prepDestContext(destFile string, rs io.ReadSeeker, conf *model.Configuratio
}
}

ctxDest.EnsureVersionForWriting()
if ctxDest.Version() < model.V20 {
ctxDest.EnsureVersionForWriting()
}

return ctxDest, nil
}
Expand Down Expand Up @@ -135,9 +137,6 @@ func Merge(destFile string, inFiles []string, w io.Writer, conf *model.Configura
if err != nil {
return err
}
if ctxDest.Version() == model.V20 {
return pdfcpu.ErrUnsupportedVersion
}

for _, fName := range inFiles {
if err := func() error {
Expand Down Expand Up @@ -181,6 +180,7 @@ func MergeCreateFile(inFiles []string, outFile string, dividerPage bool, conf *m
return
}
os.Remove(outFile)
return
}
if err = f.Close(); err != nil {
return
Expand Down
4 changes: 0 additions & 4 deletions pkg/api/nup.go
Expand Up @@ -119,10 +119,6 @@ func NUp(rs io.ReadSeeker, w io.Writer, imgFiles, selectedPages []string, nup *m
return err
}

if ctx.Version() == model.V20 {
return pdfcpu.ErrUnsupportedVersion
}

if err := ctx.EnsurePageCount(); err != nil {
return err
}
Expand Down
39 changes: 24 additions & 15 deletions pkg/api/page.go
Expand Up @@ -19,9 +19,11 @@ package api
import (
"io"
"os"
"sort"
"time"

"github.com/pdfcpu/pdfcpu/pkg/log"
"github.com/pdfcpu/pdfcpu/pkg/pdfcpu"
"github.com/pdfcpu/pdfcpu/pkg/pdfcpu/model"
"github.com/pdfcpu/pdfcpu/pkg/pdfcpu/types"
"github.com/pkg/errors"
Expand Down Expand Up @@ -134,7 +136,7 @@ func RemovePages(rs io.ReadSeeker, w io.Writer, selectedPages []string, conf *mo
conf.Cmd = model.REMOVEPAGES

fromStart := time.Now()
ctx, durRead, durVal, durOpt, err := ReadValidateAndOptimize(rs, conf, fromStart)
ctx, _, _, _, err := ReadValidateAndOptimize(rs, conf, fromStart)
if err != nil {
return err
}
Expand All @@ -143,31 +145,38 @@ func RemovePages(rs io.ReadSeeker, w io.Writer, selectedPages []string, conf *mo
return err
}

fromWrite := time.Now()

pages, err := PagesForPageSelection(ctx.PageCount, selectedPages, false, true)
pages, err := RemainingPagesForPageRemoval(ctx.PageCount, selectedPages, true)
if err != nil {
return err
}

// ctx.Pagecount gets set during validation.
if len(pages) >= ctx.PageCount {
return errors.New("pdfcpu: operation invalid")
if len(pages) == 0 {
if log.CLIEnabled() {
log.CLI.Println("aborted: missing page numbers!")
}
return nil
}

// No special context processing required.
// WriteContext decides which pages get written by checking conf.Cmd
var pageNrs []int
for k, v := range pages {
if v {
pageNrs = append(pageNrs, k)
}
}
sort.Ints(pageNrs)

ctx.Write.SelectedPages = pages
if err = WriteContext(ctx, w); err != nil {
ctxDest, err := pdfcpu.ExtractPages(ctx, pageNrs, false)
if err != nil {
return err
}

durWrite := time.Since(fromWrite).Seconds()
durTotal := time.Since(fromStart).Seconds()
logOperationStats(ctx, "remove pages, write", durRead, durVal, durOpt, durWrite, durTotal)
if conf.ValidationMode != model.ValidationNone {
if err = ValidateContext(ctxDest); err != nil {
return err
}
}

return nil
return WriteContext(ctxDest, w)
}

// RemovePagesFile removes selected inFile pages and writes the result to outFile..
Expand Down
9 changes: 0 additions & 9 deletions pkg/api/pageLayout.go
Expand Up @@ -21,7 +21,6 @@ import (
"os"
"time"

"github.com/pdfcpu/pdfcpu/pkg/pdfcpu"
"github.com/pdfcpu/pdfcpu/pkg/pdfcpu/model"
"github.com/pdfcpu/pdfcpu/pkg/pdfcpu/types"
"github.com/pkg/errors"
Expand Down Expand Up @@ -113,10 +112,6 @@ func SetPageLayout(rs io.ReadSeeker, w io.Writer, val model.PageLayout, conf *mo
return err
}

if ctx.Version() == model.V20 {
return pdfcpu.ErrUnsupportedVersion
}

ctx.RootDict["PageLayout"] = types.Name(val.String())

if err = WriteContext(ctx, w); err != nil {
Expand Down Expand Up @@ -182,10 +177,6 @@ func ResetPageLayout(rs io.ReadSeeker, w io.Writer, conf *model.Configuration) e
return err
}

if ctx.Version() == model.V20 {
return pdfcpu.ErrUnsupportedVersion
}

delete(ctx.RootDict, "PageLayout")

if err = WriteContext(ctx, w); err != nil {
Expand Down
9 changes: 0 additions & 9 deletions pkg/api/pageMode.go
Expand Up @@ -21,7 +21,6 @@ import (
"os"
"time"

"github.com/pdfcpu/pdfcpu/pkg/pdfcpu"
"github.com/pdfcpu/pdfcpu/pkg/pdfcpu/model"
"github.com/pdfcpu/pdfcpu/pkg/pdfcpu/types"
"github.com/pkg/errors"
Expand Down Expand Up @@ -113,10 +112,6 @@ func SetPageMode(rs io.ReadSeeker, w io.Writer, val model.PageMode, conf *model.
return err
}

if ctx.Version() == model.V20 {
return pdfcpu.ErrUnsupportedVersion
}

ctx.RootDict["PageMode"] = types.Name(val.String())

if err = WriteContext(ctx, w); err != nil {
Expand Down Expand Up @@ -182,10 +177,6 @@ func ResetPageMode(rs io.ReadSeeker, w io.Writer, conf *model.Configuration) err
return err
}

if ctx.Version() == model.V20 {
return pdfcpu.ErrUnsupportedVersion
}

delete(ctx.RootDict, "PageMode")

if err = WriteContext(ctx, w); err != nil {
Expand Down
10 changes: 10 additions & 0 deletions pkg/api/permission.go
Expand Up @@ -21,6 +21,7 @@ import (
"os"
"time"

"github.com/pdfcpu/pdfcpu/pkg/pdfcpu"
"github.com/pdfcpu/pdfcpu/pkg/pdfcpu/model"
"github.com/pkg/errors"
)
Expand Down Expand Up @@ -68,6 +69,10 @@ func SetPermissions(rs io.ReadSeeker, w io.Writer, conf *model.Configuration) er
return err
}

if ctx.Version() == model.V20 {
return pdfcpu.ErrUnsupportedVersion
}

fromWrite := time.Now()
if err = WriteContext(ctx, w); err != nil {
return err
Expand Down Expand Up @@ -141,6 +146,11 @@ func GetPermissions(rs io.ReadSeeker, conf *model.Configuration) (*int16, error)
if err != nil {
return nil, err
}

if ctx.Version() == model.V20 {
return nil, pdfcpu.ErrUnsupportedVersion
}

if ctx.E == nil {
// Full access - permissions don't apply.
return nil, nil
Expand Down
20 changes: 20 additions & 0 deletions pkg/api/selectPages.go
Expand Up @@ -391,6 +391,26 @@ func PagesForPageSelection(pageCount int, pageSelection []string, ensureAllforNo
return m, nil
}

func RemainingPagesForPageRemoval(pageCount int, pageSelection []string, log bool) (types.IntSet, error) {
pagesToRemove, err := selectedPages(pageCount, pageSelection, log)
if err != nil {
return nil, err
}

m := types.IntSet{}
for i := 1; i <= pageCount; i++ {
m[i] = true
}

for k, v := range pagesToRemove {
if v {
m[k] = false
}
}

return m, nil
}

func deletePageFromCollection(cp *[]int, p int) {
a := []int{}
for _, i := range *cp {
Expand Down

0 comments on commit 694f81f

Please sign in to comment.