diff --git a/pkg/api/annotation.go b/pkg/api/annotation.go index 19ef6119..c3cfc27d 100644 --- a/pkg/api/annotation.go +++ b/pkg/api/annotation.go @@ -20,7 +20,6 @@ import ( "io" "os" - "github.com/pdfcpu/pdfcpu/pkg/log" "github.com/pdfcpu/pdfcpu/pkg/pdfcpu" "github.com/pdfcpu/pdfcpu/pkg/pdfcpu/model" "github.com/pkg/errors" @@ -42,10 +41,6 @@ func Annotations(rs io.ReadSeeker, selectedPages []string, conf *model.Configura return nil, err } - if err := ctx.EnsurePageCount(); err != nil { - return nil, err - } - pages, err := PagesForPageSelection(ctx.PageCount, selectedPages, true, true) if err != nil { return nil, err @@ -70,10 +65,6 @@ func AddAnnotations(rs io.ReadSeeker, w io.Writer, selectedPages []string, ann m return err } - if err := ctx.EnsurePageCount(); err != nil { - return err - } - pages, err := PagesForPageSelection(ctx.PageCount, selectedPages, true, true) if err != nil { return err @@ -87,15 +78,7 @@ func AddAnnotations(rs io.ReadSeeker, w io.Writer, selectedPages []string, ann m return errors.New("pdfcpu: AddAnnotations: No annotations added") } - if log.StatsEnabled() { - log.Stats.Printf("XRefTable:\n%s\n", ctx) - } - - if err = ValidateContext(ctx); err != nil { - return err - } - - return WriteContext(ctx, w) + return Write(ctx, w, conf) } // AddAnnotationsAsIncrement adds annotations for selected pages in rws and writes out a PDF increment. @@ -118,10 +101,6 @@ func AddAnnotationsAsIncrement(rws io.ReadWriteSeeker, selectedPages []string, a return errors.New("Incremental writing not supported for PDF version < V1.4 (Hint: Use pdfcpu optimize then try again)") } - if err := ctx.EnsurePageCount(); err != nil { - return err - } - pages, err := PagesForPageSelection(ctx.PageCount, selectedPages, true, true) if err != nil { return err @@ -135,19 +114,7 @@ func AddAnnotationsAsIncrement(rws io.ReadWriteSeeker, selectedPages []string, a return errors.New("pdfcpu: AddAnnotationsAsIncrement: No annotations added") } - if log.StatsEnabled() { - log.Stats.Printf("XRefTable:\n%s\n", ctx) - } - - if err = ValidateContext(ctx); err != nil { - return err - } - - if _, err = rws.Seek(0, io.SeekEnd); err != nil { - return err - } - - return WriteIncrement(ctx, rws) + return WriteIncr(ctx, rws, conf) } // AddAnnotationsFile adds annotations for selected pages to a PDF context read from inFile and writes the result to outFile. @@ -216,10 +183,6 @@ func AddAnnotationsMap(rs io.ReadSeeker, w io.Writer, m map[int][]model.Annotati return err } - if err := ctx.EnsurePageCount(); err != nil { - return err - } - ok, err := pdfcpu.AddAnnotationsMap(ctx, m, false) if err != nil { return err @@ -228,15 +191,7 @@ func AddAnnotationsMap(rs io.ReadSeeker, w io.Writer, m map[int][]model.Annotati return errors.New("pdfcpu: AddAnnotationsMap: No annotations added") } - if log.StatsEnabled() { - log.Stats.Printf("XRefTable:\n%s\n", ctx) - } - - if err = ValidateContext(ctx); err != nil { - return err - } - - return WriteContext(ctx, w) + return Write(ctx, w, conf) } // AddAnnotationsMapAsIncrement adds annotations in m to corresponding pages of rws and writes out a PDF increment. @@ -259,10 +214,6 @@ func AddAnnotationsMapAsIncrement(rws io.ReadWriteSeeker, m map[int][]model.Anno return errors.New("Increment writing not supported for PDF version < V1.4 (Hint: Use pdfcpu optimize then try again)") } - if err := ctx.EnsurePageCount(); err != nil { - return err - } - ok, err := pdfcpu.AddAnnotationsMap(ctx, m, true) if err != nil { return err @@ -271,19 +222,7 @@ func AddAnnotationsMapAsIncrement(rws io.ReadWriteSeeker, m map[int][]model.Anno return errors.New("pdfcpu: AddAnnotationsMapAsIncrement: No annotations added") } - if log.StatsEnabled() { - log.Stats.Printf("XRefTable:\n%s\n", ctx) - } - - if err = ValidateContext(ctx); err != nil { - return err - } - - if _, err = rws.Seek(0, io.SeekEnd); err != nil { - return err - } - - return WriteIncrement(ctx, rws) + return WriteIncr(ctx, rws, conf) } // AddAnnotationsMapFile adds annotations in m to corresponding pages of inFile and writes the result to outFile. @@ -354,10 +293,6 @@ func RemoveAnnotations(rs io.ReadSeeker, w io.Writer, selectedPages, idsAndTypes return err } - if err := ctx.EnsurePageCount(); err != nil { - return err - } - pages, err := PagesForPageSelection(ctx.PageCount, selectedPages, true, true) if err != nil { return err @@ -371,15 +306,7 @@ func RemoveAnnotations(rs io.ReadSeeker, w io.Writer, selectedPages, idsAndTypes return errors.New("pdfcpu: RemoveAnnotations: No annotation removed") } - if log.StatsEnabled() { - log.Stats.Printf("XRefTable:\n%s\n", ctx) - } - - if err = ValidateContext(ctx); err != nil { - return err - } - - return WriteContext(ctx, w) + return Write(ctx, w, conf) } // RemoveAnnotationsAsIncrement removes annotations for selected pages by ids and object number @@ -403,10 +330,6 @@ func RemoveAnnotationsAsIncrement(rws io.ReadWriteSeeker, selectedPages, idsAndT return errors.New("pdfcpu: Incremental writing unsupported for PDF version < V1.4 (Hint: Use pdfcpu optimize then try again)") } - if err := ctx.EnsurePageCount(); err != nil { - return err - } - pages, err := PagesForPageSelection(ctx.PageCount, selectedPages, true, true) if err != nil { return err @@ -420,19 +343,7 @@ func RemoveAnnotationsAsIncrement(rws io.ReadWriteSeeker, selectedPages, idsAndT return errors.New("pdfcpu: RemoveAnnotationsAsIncrement: No annotation removed") } - if log.StatsEnabled() { - log.Stats.Printf("XRefTable:\n%s\n", ctx) - } - - if err = ValidateContext(ctx); err != nil { - return err - } - - if _, err = rws.Seek(0, io.SeekEnd); err != nil { - return err - } - - return WriteIncrement(ctx, rws) + return WriteIncr(ctx, rws, conf) } // RemoveAnnotationsFile removes annotations for selected pages by id and object number diff --git a/pkg/api/api.go b/pkg/api/api.go index 789fcad1..4ae614a6 100644 --- a/pkg/api/api.go +++ b/pkg/api/api.go @@ -55,6 +55,7 @@ func logDisclaimerPDF20() { * 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 * +* Thank you for using pdfcpu <3 * *********************************************************************` if log.ValidateEnabled() { @@ -99,11 +100,9 @@ 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) } @@ -149,11 +148,7 @@ func ReadAndValidate(rs io.ReadSeeker, conf *model.Configuration) (ctx *model.Co return nil, err } - if ctx.Version() == model.V20 { - logDisclaimerPDF20() - } - - if err = validate.XRefTable(ctx.XRefTable); err != nil { + if err := ValidateContext(ctx); err != nil { return nil, err } @@ -174,21 +169,43 @@ func ReadValidateAndOptimize(rs io.ReadSeeker, conf *model.Configuration) (ctx * return ctx, nil } -func logOperationStats(ctx *model.Context, op string, durRead, durVal, durOpt, durWrite, durTotal float64) { +func logWritingTo(s string) { + if log.CLIEnabled() { + log.CLI.Printf("writing %s...\n", s) + } +} + +func Write(ctx *model.Context, w io.Writer, conf *model.Configuration) error { if log.StatsEnabled() { log.Stats.Printf("XRefTable:\n%s\n", ctx) } - model.TimingStats(op, durRead, durVal, durOpt, durWrite, durTotal) - if ctx.Read.FileSize > 0 { - ctx.Read.LogStats(ctx.Optimized) - ctx.Write.LogStats() + + if conf.PostProcessValidate { + if err := ValidateContext(ctx); err != nil { + return err + } } + + return WriteContext(ctx, w) } -func logWritingTo(s string) { - if log.CLIEnabled() { - log.CLI.Printf("writing %s...\n", s) +func WriteIncr(ctx *model.Context, rws io.ReadWriteSeeker, conf *model.Configuration) error { + + if log.StatsEnabled() { + log.Stats.Printf("XRefTable:\n%s\n", ctx) } + + if conf.PostProcessValidate { + if err := ValidateContext(ctx); err != nil { + return err + } + } + + if _, err := rws.Seek(0, io.SeekEnd); err != nil { + return err + } + + return WriteIncrement(ctx, rws) } // EnsureDefaultConfigAt switches to the pdfcpu config dir located at path. diff --git a/pkg/api/attach.go b/pkg/api/attach.go index 7442b829..6f573650 100644 --- a/pkg/api/attach.go +++ b/pkg/api/attach.go @@ -107,11 +107,7 @@ func AddAttachments(rs io.ReadSeeker, w io.Writer, files []string, coll bool, co return errors.New("pdfcpu: AddAttachments: No attachment added") } - if err = WriteContext(ctx, w); err != nil { - return err - } - - return nil + return WriteContext(ctx, w) } // AddAttachmentsFile embeds files into a PDF context read from inFile and writes the result to outFile. @@ -180,11 +176,7 @@ func RemoveAttachments(rs io.ReadSeeker, w io.Writer, files []string, conf *mode return errors.New("pdfcpu: RemoveAttachments: No attachment removed") } - if err = WriteContext(ctx, w); err != nil { - return err - } - - return nil + return WriteContext(ctx, w) } // RemoveAttachmentsFile deletes embedded files from a PDF context read from inFile and writes the result to outFile. diff --git a/pkg/api/booklet.go b/pkg/api/booklet.go index 5af4a9fd..152da031 100644 --- a/pkg/api/booklet.go +++ b/pkg/api/booklet.go @@ -87,10 +87,6 @@ func Booklet(rs io.ReadSeeker, w io.Writer, imgFiles, selectedPages []string, nu return err } - if err := ctx.EnsurePageCount(); err != nil { - return err - } - pages, err := PagesForPageSelection(ctx.PageCount, selectedPages, true, true) if err != nil { return err @@ -101,17 +97,7 @@ func Booklet(rs io.ReadSeeker, w io.Writer, imgFiles, selectedPages []string, nu } } - if err = ValidateContext(ctx); err != nil { - return err - } - - if err = WriteContext(ctx, w); err != nil { - return err - } - - log.Stats.Printf("XRefTable:\n%s\n", ctx) - - return nil + return Write(ctx, w, conf) } // BookletFile rearranges PDF pages or images into a booklet layout and writes the result to outFile. diff --git a/pkg/api/bookmark.go b/pkg/api/bookmark.go index e2fb7af7..56072bb3 100644 --- a/pkg/api/bookmark.go +++ b/pkg/api/bookmark.go @@ -70,10 +70,6 @@ func ExportBookmarksJSON(rs io.ReadSeeker, w io.Writer, source string, conf *mod return err } - if err := ctx.EnsurePageCount(); err != nil { - return err - } - ok, err := pdfcpu.ExportBookmarksJSON(ctx, source, w) if err != nil { return err @@ -138,10 +134,6 @@ func ImportBookmarks(rs io.ReadSeeker, rd io.Reader, w io.Writer, replace bool, return err } - if err := ctx.EnsurePageCount(); err != nil { - return err - } - ok, err := pdfcpu.ImportBookmarks(ctx, rd, replace) if err != nil { return err @@ -221,11 +213,7 @@ func AddBookmarks(rs io.ReadSeeker, w io.Writer, bms []pdfcpu.Bookmark, replace return err } - if err = WriteContext(ctx, w); err != nil { - return err - } - - return nil + return WriteContext(ctx, w) } // AddBookmarksFile adds outlines to the PDF context read from inFile and writes the result to outFile. diff --git a/pkg/api/box.go b/pkg/api/box.go index 5f044472..615f0087 100644 --- a/pkg/api/box.go +++ b/pkg/api/box.go @@ -57,10 +57,6 @@ func Boxes(rs io.ReadSeeker, selectedPages []string, conf *model.Configuration) return nil, err } - if err := ctx.EnsurePageCount(); err != nil { - return nil, err - } - pages, err := PagesForPageSelection(ctx.PageCount, selectedPages, true, true) if err != nil { return nil, err @@ -85,10 +81,6 @@ func AddBoxes(rs io.ReadSeeker, w io.Writer, selectedPages []string, pb *model.P return err } - if err := ctx.EnsurePageCount(); err != nil { - return err - } - pages, err := PagesForPageSelection(ctx.PageCount, selectedPages, true, true) if err != nil { return err @@ -98,11 +90,7 @@ func AddBoxes(rs io.ReadSeeker, w io.Writer, selectedPages []string, pb *model.P return err } - if err = ValidateContext(ctx); err != nil { - return err - } - - return WriteContext(ctx, w) + return Write(ctx, w, conf) } // AddBoxesFile adds page boundaries for selected pages of inFile and writes result to outFile. @@ -166,10 +154,6 @@ func RemoveBoxes(rs io.ReadSeeker, w io.Writer, selectedPages []string, pb *mode return err } - if err := ctx.EnsurePageCount(); err != nil { - return err - } - pages, err := PagesForPageSelection(ctx.PageCount, selectedPages, true, true) if err != nil { return err @@ -179,11 +163,7 @@ func RemoveBoxes(rs io.ReadSeeker, w io.Writer, selectedPages []string, pb *mode return err } - if err = ValidateContext(ctx); err != nil { - return err - } - - return WriteContext(ctx, w) + return Write(ctx, w, conf) } // RemoveBoxesFile removes page boundaries as specified in pb for selected pages of inFile and writes result to outFile. @@ -248,10 +228,6 @@ func Crop(rs io.ReadSeeker, w io.Writer, selectedPages []string, b *model.Box, c return err } - if err := ctx.EnsurePageCount(); err != nil { - return err - } - pages, err := PagesForPageSelection(ctx.PageCount, selectedPages, true, true) if err != nil { return err @@ -261,11 +237,7 @@ func Crop(rs io.ReadSeeker, w io.Writer, selectedPages []string, b *model.Box, c return err } - if err = ValidateContext(ctx); err != nil { - return err - } - - return WriteContext(ctx, w) + return Write(ctx, w, conf) } // CropFile adds crop boxes for selected pages of inFile and writes result to outFile. diff --git a/pkg/api/collect.go b/pkg/api/collect.go index f0b67d72..7e174dd8 100644 --- a/pkg/api/collect.go +++ b/pkg/api/collect.go @@ -41,10 +41,6 @@ func Collect(rs io.ReadSeeker, w io.Writer, selectedPages []string, conf *model. return err } - if err := ctx.EnsurePageCount(); err != nil { - return err - } - pages, err := PagesForPageCollection(ctx.PageCount, selectedPages) if err != nil { return err @@ -55,11 +51,7 @@ func Collect(rs io.ReadSeeker, w io.Writer, selectedPages []string, conf *model. return err } - if err = ValidateContext(ctxDest); err != nil { - return err - } - - return WriteContext(ctxDest, w) + return Write(ctxDest, w, conf) } // CollectFile creates a custom PDF page sequence for inFile and writes the result to outFile. diff --git a/pkg/api/create.go b/pkg/api/create.go index 47854509..21fd6dea 100644 --- a/pkg/api/create.go +++ b/pkg/api/create.go @@ -66,16 +66,14 @@ func Create(rs io.ReadSeeker, rd io.Reader, w io.Writer, conf *model.Configurati return err } - if err := ctx.EnsurePageCount(); err != nil { - return err - } - if err := create.FromJSON(ctx, rd); err != nil { return err } - if err = ValidateContext(ctx); err != nil { - return err + if conf.PostProcessValidate { + if err = ValidateContext(ctx); err != nil { + return err + } } return WriteContext(ctx, w) diff --git a/pkg/api/cut.go b/pkg/api/cut.go index 141506ba..a6d81f7b 100644 --- a/pkg/api/cut.go +++ b/pkg/api/cut.go @@ -32,21 +32,17 @@ import ( ) func prepareForCut(rs io.ReadSeeker, selectedPages []string, conf *model.Configuration) (*model.Context, types.IntSet, error) { - ctxSrc, err := ReadValidateAndOptimize(rs, conf) + ctx, err := ReadValidateAndOptimize(rs, conf) if err != nil { return nil, nil, err } - if err := ctxSrc.EnsurePageCount(); err != nil { - return nil, nil, err - } - - pages, err := PagesForPageSelection(ctxSrc.PageCount, selectedPages, true, true) + pages, err := PagesForPageSelection(ctx.PageCount, selectedPages, true, true) if err != nil { return nil, nil, err } - return ctxSrc, pages, nil + return ctx, pages, nil } // Poster applies cut for selected pages of rs and generates corresponding poster tiles in outDir. @@ -94,14 +90,15 @@ func Poster(rs io.ReadSeeker, outDir, fileName string, selectedPages []string, c outFile := filepath.Join(outDir, fmt.Sprintf("%s_page_%d.pdf", fileName, i)) logWritingTo(outFile) - if err := WriteContextFile(ctxDest, outFile); err != nil { - return err + if conf.PostProcessValidate { + if err = ValidateContext(ctxDest); err != nil { + return err + } } - if err = ValidateContext(ctxDest); err != nil { + if err := WriteContextFile(ctxDest, outFile); err != nil { return err } - } return nil @@ -156,6 +153,12 @@ func NDown(rs io.ReadSeeker, outDir, fileName string, selectedPages []string, n return err } + if conf.PostProcessValidate { + if err = ValidateContext(ctxDest); err != nil { + return err + } + } + outFile := filepath.Join(outDir, fmt.Sprintf("%s_page_%d.pdf", fileName, i)) if log.CLIEnabled() { log.CLI.Printf("writing %s\n", outFile) @@ -163,10 +166,6 @@ func NDown(rs io.ReadSeeker, outDir, fileName string, selectedPages []string, n if err := WriteContextFile(ctxDest, outFile); err != nil { return err } - - if err = ValidateContext(ctxDest); err != nil { - return err - } } return nil @@ -258,16 +257,18 @@ func Cut(rs io.ReadSeeker, outDir, fileName string, selectedPages []string, cut return err } + if conf.PostProcessValidate { + if err = ValidateContext(ctxDest); err != nil { + return err + } + } + outFile := filepath.Join(outDir, fmt.Sprintf("%s_page_%d.pdf", fileName, i)) logWritingTo(outFile) if err := WriteContextFile(ctxDest, outFile); err != nil { return err } - - if err = ValidateContext(ctxDest); err != nil { - return err - } } return nil diff --git a/pkg/api/extract.go b/pkg/api/extract.go index fb2b3596..946a47b2 100644 --- a/pkg/api/extract.go +++ b/pkg/api/extract.go @@ -48,10 +48,6 @@ func ExtractImagesRaw(rs io.ReadSeeker, selectedPages []string, conf *model.Conf return nil, err } - if err := ctx.EnsurePageCount(); err != nil { - return nil, err - } - pages, err := PagesForPageSelection(ctx.PageCount, selectedPages, true, true) if err != nil { return nil, err @@ -88,10 +84,6 @@ func ExtractImages(rs io.ReadSeeker, selectedPages []string, digestImage func(mo return err } - if err := ctx.EnsurePageCount(); err != nil { - return err - } - pages, err := PagesForPageSelection(ctx.PageCount, selectedPages, true, true) if err != nil { return err @@ -175,10 +167,6 @@ func ExtractFonts(rs io.ReadSeeker, outDir, fileName string, selectedPages []str return err } - if err := ctx.EnsurePageCount(); err != nil { - return err - } - pages, err := PagesForPageSelection(ctx.PageCount, selectedPages, true, true) if err != nil { return err @@ -238,10 +226,6 @@ func ExtractPages(rs io.ReadSeeker, outDir, fileName string, selectedPages []str return err } - if err := ctx.EnsurePageCount(); err != nil { - return err - } - pages, err := PagesForPageSelection(ctx.PageCount, selectedPages, true, true) if err != nil { return err @@ -305,10 +289,6 @@ func ExtractContent(rs io.ReadSeeker, outDir, fileName string, selectedPages []s return err } - if err := ctx.EnsurePageCount(); err != nil { - return err - } - pages, err := PagesForPageSelection(ctx.PageCount, selectedPages, true, true) if err != nil { return err diff --git a/pkg/api/form.go b/pkg/api/form.go index 458cb603..711bfb08 100644 --- a/pkg/api/form.go +++ b/pkg/api/form.go @@ -57,10 +57,6 @@ func FormFields(rs io.ReadSeeker, conf *model.Configuration) ([]form.Field, erro return nil, err } - if err := ctx.EnsurePageCount(); err != nil { - return nil, err - } - fields, _, err := form.FormFields(ctx) return fields, err @@ -82,10 +78,6 @@ func RemoveFormFields(rs io.ReadSeeker, w io.Writer, fieldIDsOrNames []string, c return err } - if err := ctx.EnsurePageCount(); err != nil { - return err - } - ok, err := form.RemoveFormFields(ctx, fieldIDsOrNames) if err != nil { return err @@ -94,11 +86,7 @@ func RemoveFormFields(rs io.ReadSeeker, w io.Writer, fieldIDsOrNames []string, c return ErrNoFormFieldsAffected } - if err = ValidateContext(ctx); err != nil { - return err - } - - return WriteContext(ctx, w) + return Write(ctx, w, conf) } // RemoveFormFieldsFile deletes form fields in inFile and writes the result to outFile. @@ -157,10 +145,6 @@ func LockFormFields(rs io.ReadSeeker, w io.Writer, fieldIDsOrNames []string, con return err } - if err := ctx.EnsurePageCount(); err != nil { - return err - } - ok, err := form.LockFormFields(ctx, fieldIDsOrNames) if err != nil { return err @@ -169,11 +153,7 @@ func LockFormFields(rs io.ReadSeeker, w io.Writer, fieldIDsOrNames []string, con return ErrNoFormFieldsAffected } - if err = ValidateContext(ctx); err != nil { - return err - } - - return WriteContext(ctx, w) + return Write(ctx, w, conf) } // LockFormFieldsFile turns form fields of inFile into read-only and writes the result to outFile. @@ -232,10 +212,6 @@ func UnlockFormFields(rs io.ReadSeeker, w io.Writer, fieldIDsOrNames []string, c return err } - if err := ctx.EnsurePageCount(); err != nil { - return err - } - ok, err := form.UnlockFormFields(ctx, fieldIDsOrNames) if err != nil { return err @@ -244,11 +220,7 @@ func UnlockFormFields(rs io.ReadSeeker, w io.Writer, fieldIDsOrNames []string, c return ErrNoFormFieldsAffected } - if err = ValidateContext(ctx); err != nil { - return err - } - - return WriteContext(ctx, w) + return Write(ctx, w, conf) } // UnlockFormFieldsFile makes form fields of inFile writeable and writes the result to outFile. @@ -307,10 +279,6 @@ func ResetFormFields(rs io.ReadSeeker, w io.Writer, fieldIDsOrNames []string, co return err } - if err := ctx.EnsurePageCount(); err != nil { - return err - } - ok, err := form.ResetFormFields(ctx, fieldIDsOrNames) if err != nil { return err @@ -319,11 +287,7 @@ func ResetFormFields(rs io.ReadSeeker, w io.Writer, fieldIDsOrNames []string, co return ErrNoFormFieldsAffected } - if err = ValidateContext(ctx); err != nil { - return err - } - - return WriteContext(ctx, w) + return Write(ctx, w, conf) } // ResetFormFieldsFile resets form fields of inFile and writes the result to outFile. @@ -382,10 +346,6 @@ func ExportForm(rs io.ReadSeeker, source string, conf *model.Configuration) (*fo return nil, err } - if err := ctx.EnsurePageCount(); err != nil { - return nil, err - } - formGroup, ok, err := form.ExportForm(ctx.XRefTable, source) if err != nil { return nil, err @@ -417,10 +377,6 @@ func ExportFormJSON(rs io.ReadSeeker, w io.Writer, source string, conf *model.Co return err } - if err := ctx.EnsurePageCount(); err != nil { - return err - } - ok, err := form.ExportFormJSON(ctx.XRefTable, source, w) if err != nil { return err @@ -523,7 +479,7 @@ func validateOptionValues(f form.Form) error { return nil } -func fillPostProc(ctx *model.Context, pp []*model.Page, conf *model.Configuration) error { +func fillPostProc(ctx *model.Context, pp []*model.Page) error { if _, _, err := create.UpdatePageTree(ctx, pp, nil); err != nil { return err } @@ -553,10 +509,6 @@ func FillForm(rs io.ReadSeeker, rd io.Reader, w io.Writer, conf *model.Configura ctx.RemoveSignature() - if err := ctx.EnsurePageCount(); err != nil { - return err - } - var buf bytes.Buffer if _, err := io.Copy(&buf, rd); err != nil { return err @@ -596,11 +548,11 @@ func FillForm(rs io.ReadSeeker, rd io.Reader, w io.Writer, conf *model.Configura return ErrNoFormFieldsAffected } - if err := fillPostProc(ctx, pp, conf); err != nil { + if err := fillPostProc(ctx, pp); err != nil { return err } - return WriteContext(ctx, w) + return Write(ctx, w, conf) } // FillFormFile populates the form inFilePDF with data from inFileJSON and writes the result to outFilePDF. @@ -716,10 +668,6 @@ func multiFillFormJSON(inFilePDF string, rd io.Reader, outDir, fileName string, return err } - if err := ctx.EnsurePageCount(); err != nil { - return err - } - ok, pp, err := form.FillForm(ctx, form.FillDetails(&f, nil), f.Pages, form.JSON) if err != nil { return err @@ -732,8 +680,10 @@ func multiFillFormJSON(inFilePDF string, rd io.Reader, outDir, fileName string, return err } - if err = ValidateContext(ctx); err != nil { - return err + if conf.PostProcessValidate { + if err = ValidateContext(ctx); err != nil { + return err + } } outFile := filepath.Join(outDir, fmt.Sprintf("%s_%02d.pdf", fileName, i+1)) @@ -808,10 +758,6 @@ func multiFillFormCSV(inFilePDF string, rd io.Reader, outDir, fileName string, m return err } - if err := ctx.EnsurePageCount(); err != nil { - return err - } - fieldMap, imgPageMap, err := form.FieldMap(fieldNames, formRecord) if err != nil { return err @@ -829,8 +775,10 @@ func multiFillFormCSV(inFilePDF string, rd io.Reader, outDir, fileName string, m return err } - if err = ValidateContext(ctx); err != nil { - return err + if conf.PostProcessValidate { + if err = ValidateContext(ctx); err != nil { + return err + } } outFile := filepath.Join(outDir, fmt.Sprintf("%s_%02d.pdf", fileName, i+1)) diff --git a/pkg/api/image.go b/pkg/api/image.go index 6038fc31..c6386240 100644 --- a/pkg/api/image.go +++ b/pkg/api/image.go @@ -40,10 +40,6 @@ func Images(rs io.ReadSeeker, selectedPages []string, conf *model.Configuration) return nil, err } - if err := ctx.EnsurePageCount(); err != nil { - return nil, err - } - pages, err := PagesForPageSelection(ctx.PageCount, selectedPages, true, true) if err != nil { return nil, err diff --git a/pkg/api/importImage.go b/pkg/api/importImage.go index ae878939..3932dbf4 100644 --- a/pkg/api/importImage.go +++ b/pkg/api/importImage.go @@ -87,19 +87,7 @@ func ImportImages(rs io.ReadSeeker, w io.Writer, imgs []io.Reader, imp *pdfcpu.I ctx.PageCount++ } - if err = ValidateContext(ctx); err != nil { - return err - } - - if err = WriteContext(ctx, w); err != nil { - return err - } - - if log.StatsEnabled() { - log.Stats.Printf("XRefTable:\n%s\n", ctx) - } - - return nil + return Write(ctx, w, conf) } func fileExists(filename string) bool { diff --git a/pkg/api/info.go b/pkg/api/info.go index bed022f9..b23862fb 100644 --- a/pkg/api/info.go +++ b/pkg/api/info.go @@ -42,10 +42,6 @@ func PDFInfo(rs io.ReadSeeker, fileName string, selectedPages []string, conf *mo return nil, err } - if err := ctx.EnsurePageCount(); err != nil { - return nil, err - } - pages, err := PagesForPageSelection(ctx.PageCount, selectedPages, false, true) if err != nil { return nil, err diff --git a/pkg/api/keyword.go b/pkg/api/keyword.go index 143f2f20..58e2d3d6 100644 --- a/pkg/api/keyword.go +++ b/pkg/api/keyword.go @@ -68,7 +68,7 @@ func AddKeywords(rs io.ReadSeeker, w io.Writer, files []string, conf *model.Conf return err } - return WriteContext(ctx, w) + return Write(ctx, w, conf) } // AddKeywordsFile adds keywords to inFile's infodict and writes the result to outFile. @@ -135,7 +135,7 @@ func RemoveKeywords(rs io.ReadSeeker, w io.Writer, keywords []string, conf *mode return errors.New("no keyword removed") } - return WriteContext(ctx, w) + return Write(ctx, w, conf) } // RemoveKeywordsFile deletes keywords from inFile's infodict and writes the result to outFile. diff --git a/pkg/api/nup.go b/pkg/api/nup.go index 3534e888..4dfcabf8 100644 --- a/pkg/api/nup.go +++ b/pkg/api/nup.go @@ -118,10 +118,6 @@ func NUp(rs io.ReadSeeker, w io.Writer, imgFiles, selectedPages []string, nup *m return err } - if err := ctx.EnsurePageCount(); err != nil { - return err - } - pages, err := PagesForPageSelection(ctx.PageCount, selectedPages, true, true) if err != nil { return err @@ -135,19 +131,7 @@ func NUp(rs io.ReadSeeker, w io.Writer, imgFiles, selectedPages []string, nup *m } - if err = ValidateContext(ctx); err != nil { - return err - } - - if err = WriteContext(ctx, w); err != nil { - return err - } - - if log.StatsEnabled() { - log.Stats.Printf("XRefTable:\n%s\n", ctx) - } - - return nil + return Write(ctx, w, conf) } // NUpFile rearranges PDF pages or images into page grids and writes the result to outFile. diff --git a/pkg/api/page.go b/pkg/api/page.go index b10a1d88..6d5638bf 100644 --- a/pkg/api/page.go +++ b/pkg/api/page.go @@ -47,10 +47,6 @@ func InsertPages(rs io.ReadSeeker, w io.Writer, selectedPages []string, before b return err } - if err := ctx.EnsurePageCount(); err != nil { - return err - } - pages, err := PagesForPageSelection(ctx.PageCount, selectedPages, true, true) if err != nil { return err @@ -60,23 +56,7 @@ func InsertPages(rs io.ReadSeeker, w io.Writer, selectedPages []string, before b return err } - if log.StatsEnabled() { - log.Stats.Printf("XRefTable:\n%s\n", ctx) - } - - if err = ValidateContext(ctx); err != nil { - return err - } - - if err = WriteContext(ctx, w); err != nil { - return err - } - - if log.StatsEnabled() { - log.Stats.Printf("XRefTable:\n%s\n", ctx) - } - - return nil + return Write(ctx, w, conf) } // InsertPagesFile inserts a blank page before or after every inFile page selected and writes the result to w. @@ -136,10 +116,6 @@ func RemovePages(rs io.ReadSeeker, w io.Writer, selectedPages []string, conf *mo return err } - if err := ctx.EnsurePageCount(); err != nil { - return err - } - pages, err := RemainingPagesForPageRemoval(ctx.PageCount, selectedPages, true) if err != nil { return err @@ -165,11 +141,7 @@ func RemovePages(rs io.ReadSeeker, w io.Writer, selectedPages []string, conf *mo return err } - if err = ValidateContext(ctxDest); err != nil { - return err - } - - return WriteContext(ctxDest, w) + return Write(ctxDest, w, conf) } // RemovePagesFile removes selected inFile pages and writes the result to outFile.. @@ -219,15 +191,11 @@ func PageCount(rs io.ReadSeeker, conf *model.Configuration) (int, error) { return 0, errors.New("pdfcpu: PageCount: missing rs") } - ctx, err := ReadContext(rs, conf) + ctx, err := ReadAndValidate(rs, conf) if err != nil { return 0, err } - if err := ValidateContext(ctx); err != nil { - return 0, err - } - return ctx.PageCount, nil } @@ -248,15 +216,11 @@ func PageDims(rs io.ReadSeeker, conf *model.Configuration) ([]types.Dim, error) return nil, errors.New("pdfcpu: PageDims: missing rs") } - ctx, err := ReadContext(rs, conf) + ctx, err := ReadAndValidate(rs, conf) if err != nil { return nil, err } - if err := ValidateContext(ctx); err != nil { - return nil, err - } - pd, err := ctx.PageDims() if err != nil { return nil, err diff --git a/pkg/api/pageLayout.go b/pkg/api/pageLayout.go index 9ad171aa..e7f143df 100644 --- a/pkg/api/pageLayout.go +++ b/pkg/api/pageLayout.go @@ -113,11 +113,7 @@ func SetPageLayout(rs io.ReadSeeker, w io.Writer, val model.PageLayout, conf *mo ctx.RootDict["PageLayout"] = types.Name(val.String()) - if err = WriteContext(ctx, w); err != nil { - return err - } - - return nil + return Write(ctx, w, conf) } // SetPageLayoutFile sets inFile's page layout and writes the result to outFile. @@ -178,11 +174,7 @@ func ResetPageLayout(rs io.ReadSeeker, w io.Writer, conf *model.Configuration) e delete(ctx.RootDict, "PageLayout") - if err = WriteContext(ctx, w); err != nil { - return err - } - - return nil + return Write(ctx, w, conf) } // ResetPageLayoutFile resets inFile's page layout and writes the result to outFile. diff --git a/pkg/api/pageMode.go b/pkg/api/pageMode.go index aca8a275..1ae43b35 100644 --- a/pkg/api/pageMode.go +++ b/pkg/api/pageMode.go @@ -113,11 +113,7 @@ func SetPageMode(rs io.ReadSeeker, w io.Writer, val model.PageMode, conf *model. ctx.RootDict["PageMode"] = types.Name(val.String()) - if err = WriteContext(ctx, w); err != nil { - return err - } - - return nil + return Write(ctx, w, conf) } // SetPageModeFile sets inFile's page mode and writes the result to outFile. @@ -178,11 +174,7 @@ func ResetPageMode(rs io.ReadSeeker, w io.Writer, conf *model.Configuration) err delete(ctx.RootDict, "PageMode") - if err = WriteContext(ctx, w); err != nil { - return err - } - - return nil + return Write(ctx, w, conf) } // ResetPageModeFile resets inFile's page mode and writes the result to outFile. diff --git a/pkg/api/property.go b/pkg/api/property.go index c89f8972..38767488 100644 --- a/pkg/api/property.go +++ b/pkg/api/property.go @@ -67,7 +67,7 @@ func AddProperties(rs io.ReadSeeker, w io.Writer, properties map[string]string, return err } - return WriteContext(ctx, w) + return Write(ctx, w, conf) } // AddPropertiesFile adds properties to inFile's infodict and writes the result to outFile. @@ -134,7 +134,7 @@ func RemoveProperties(rs io.ReadSeeker, w io.Writer, properties []string, conf * return errors.New("no property removed") } - return WriteContext(ctx, w) + return Write(ctx, w, conf) } // RemovePropertiesFile deletes properties from inFile's infodict and writes the result to outFile. diff --git a/pkg/api/resize.go b/pkg/api/resize.go index 7476f6cd..d2d5ec9e 100644 --- a/pkg/api/resize.go +++ b/pkg/api/resize.go @@ -42,10 +42,6 @@ func Resize(rs io.ReadSeeker, w io.Writer, selectedPages []string, resize *model return err } - if err := ctx.EnsurePageCount(); err != nil { - return err - } - pages, err := PagesForPageSelection(ctx.PageCount, selectedPages, true, true) if err != nil { return err @@ -55,11 +51,7 @@ func Resize(rs io.ReadSeeker, w io.Writer, selectedPages []string, resize *model return err } - if err = ValidateContext(ctx); err != nil { - return err - } - - return WriteContext(ctx, w) + return Write(ctx, w, conf) } // ResizeFile applies resizeConf for selected pages of inFile and writes result to outFile. diff --git a/pkg/api/rotate.go b/pkg/api/rotate.go index bb3b1f8b..55a53828 100644 --- a/pkg/api/rotate.go +++ b/pkg/api/rotate.go @@ -41,10 +41,6 @@ func Rotate(rs io.ReadSeeker, w io.Writer, rotation int, selectedPages []string, return err } - if err := ctx.EnsurePageCount(); err != nil { - return err - } - pages, err := PagesForPageSelection(ctx.PageCount, selectedPages, true, true) if err != nil { return err @@ -54,11 +50,7 @@ func Rotate(rs io.ReadSeeker, w io.Writer, rotation int, selectedPages []string, return err } - if err = ValidateContext(ctx); err != nil { - return err - } - - return WriteContext(ctx, w) + return Write(ctx, w, conf) } // RotateFile rotates selected pages of inFile clockwise by rotation degrees and writes the result to outFile. diff --git a/pkg/api/split.go b/pkg/api/split.go index f9db3f98..15fe26aa 100644 --- a/pkg/api/split.go +++ b/pkg/api/split.go @@ -83,16 +83,7 @@ func context(rs io.ReadSeeker, conf *model.Configuration) (*model.Context, error } conf.Cmd = model.SPLIT - ctx, err := ReadValidateAndOptimize(rs, conf) - if err != nil { - return nil, err - } - - if err := ctx.EnsurePageCount(); err != nil { - return nil, err - } - - return ctx, nil + return ReadValidateAndOptimize(rs, conf) } func pageSpansSplitAlongBookmarks(ctx *model.Context) ([]*PageSpan, error) { diff --git a/pkg/api/stamp.go b/pkg/api/stamp.go index c00b6424..d84f2c7d 100644 --- a/pkg/api/stamp.go +++ b/pkg/api/stamp.go @@ -20,7 +20,6 @@ import ( "io" "os" - "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" @@ -56,15 +55,7 @@ func AddWatermarksMap(rs io.ReadSeeker, w io.Writer, m map[int]*model.Watermark, return err } - if log.StatsEnabled() { - log.Stats.Printf("XRefTable:\n%s\n", ctx) - } - - if err = ValidateContext(ctx); err != nil { - return err - } - - return WriteContext(ctx, w) + return Write(ctx, w, conf) } // AddWatermarksMapFile adds watermarks to corresponding pages in m of inFile and writes the result to outFile. @@ -132,15 +123,7 @@ func AddWatermarksSliceMap(rs io.ReadSeeker, w io.Writer, m map[int][]*model.Wat return err } - if log.StatsEnabled() { - log.Stats.Printf("XRefTable:\n%s\n", ctx) - } - - if err = ValidateContext(ctx); err != nil { - return err - } - - return WriteContext(ctx, w) + return Write(ctx, w, conf) } // AddWatermarksSliceMapFile adds watermarks to corresponding pages in m of inFile and writes the result to outFile. @@ -205,10 +188,6 @@ func AddWatermarks(rs io.ReadSeeker, w io.Writer, selectedPages []string, wm *mo return err } - if err := ctx.EnsurePageCount(); err != nil { - return err - } - var pages types.IntSet pages, err = PagesForPageSelection(ctx.PageCount, selectedPages, true, true) if err != nil { @@ -219,15 +198,7 @@ func AddWatermarks(rs io.ReadSeeker, w io.Writer, selectedPages []string, wm *mo return err } - if log.StatsEnabled() { - log.Stats.Printf("XRefTable:\n%s\n", ctx) - } - - if err = ValidateContext(ctx); err != nil { - return err - } - - return WriteContext(ctx, w) + return Write(ctx, w, conf) } // AddWatermarksFile adds watermarks to all selected pages of inFile and writes the result to outFile. @@ -287,10 +258,6 @@ func RemoveWatermarks(rs io.ReadSeeker, w io.Writer, selectedPages []string, con return err } - if err := ctx.EnsurePageCount(); err != nil { - return err - } - pages, err := PagesForPageSelection(ctx.PageCount, selectedPages, true, true) if err != nil { return err @@ -300,15 +267,7 @@ func RemoveWatermarks(rs io.ReadSeeker, w io.Writer, selectedPages []string, con return err } - if log.StatsEnabled() { - log.Stats.Printf("XRefTable:\n%s\n", ctx) - } - - if err = ValidateContext(ctx); err != nil { - return err - } - - return WriteContext(ctx, w) + return Write(ctx, w, conf) } // RemoveWatermarksFile removes watermarks from all selected pages of inFile and writes the result to outFile. diff --git a/pkg/api/test/api_test.go b/pkg/api/test/api_test.go index 3036357d..2128326d 100644 --- a/pkg/api/test/api_test.go +++ b/pkg/api/test/api_test.go @@ -21,6 +21,7 @@ import ( "io" "os" "path/filepath" + "sort" "strings" "testing" "time" @@ -111,6 +112,7 @@ func imageFileNames(t *testing.T, dir string) []string { if err != nil { t.Fatal(err) } + sort.Strings(fn) return fn } diff --git a/pkg/api/test/box_test.go b/pkg/api/test/box_test.go index bd26e780..ca0a392f 100644 --- a/pkg/api/test/box_test.go +++ b/pkg/api/test/box_test.go @@ -42,10 +42,6 @@ func listBoxes(t *testing.T, fileName string, pb *model.PageBoundaries) ([]strin t.Fatalf("%s ReadValidateAndOptimize: %v\n", msg, err) } - if err := ctx.EnsurePageCount(); err != nil { - t.Fatalf("%s EnsurePageCount: %v\n", msg, err) - } - if pb == nil { pb = &model.PageBoundaries{} pb.SelectAll() diff --git a/pkg/api/test/form_test.go b/pkg/api/test/form_test.go index c1e90981..606f582b 100644 --- a/pkg/api/test/form_test.go +++ b/pkg/api/test/form_test.go @@ -51,10 +51,6 @@ func listFormFieldsFile(t *testing.T, inFile string, conf *model.Configuration) t.Fatalf("%s: %v\n", msg, err) } - if err := ctx.EnsurePageCount(); err != nil { - t.Fatalf("%s: %v\n", msg, err) - } - return form.ListFormFields(ctx) } diff --git a/pkg/api/trim.go b/pkg/api/trim.go index 75c8373d..ee6b79fa 100644 --- a/pkg/api/trim.go +++ b/pkg/api/trim.go @@ -44,10 +44,6 @@ func Trim(rs io.ReadSeeker, w io.Writer, selectedPages []string, conf *model.Con return err } - if err := ctx.EnsurePageCount(); err != nil { - return err - } - pages, err := PagesForPageSelection(ctx.PageCount, selectedPages, false, true) if err != nil { return err @@ -73,8 +69,10 @@ func Trim(rs io.ReadSeeker, w io.Writer, selectedPages []string, conf *model.Con return err } - if err = ValidateContext(ctxDest); err != nil { - return err + if conf.PostProcessValidate { + if err = ValidateContext(ctxDest); err != nil { + return err + } } return WriteContext(ctxDest, w) diff --git a/pkg/api/viewerPreferences.go b/pkg/api/viewerPreferences.go index e49287a0..6355146d 100644 --- a/pkg/api/viewerPreferences.go +++ b/pkg/api/viewerPreferences.go @@ -197,7 +197,7 @@ func SetViewerPreferences(rs io.ReadSeeker, w io.Writer, vp model.ViewerPreferen ctx.XRefTable.BindViewerPreferences() - return WriteContext(ctx, w) + return Write(ctx, w, conf) } // SetViewerPreferencesFromJSONBytes sets rs's viewer preferences corresponding to jsonBytes and writes the result to w. @@ -363,7 +363,7 @@ func ResetViewerPreferences(rs io.ReadSeeker, w io.Writer, conf *model.Configura delete(ctx.RootDict, "ViewerPreferences") - return WriteContext(ctx, w) + return Write(ctx, w, conf) } // ResetViewerPreferencesFile resets inFile's viewer preferences and writes the result to outFile. diff --git a/pkg/cli/list.go b/pkg/cli/list.go index f015bb94..08e9d044 100644 --- a/pkg/cli/list.go +++ b/pkg/cli/list.go @@ -125,10 +125,6 @@ func listBoxes(rs io.ReadSeeker, selectedPages []string, pb *model.PageBoundarie return nil, err } - if err := ctx.EnsurePageCount(); err != nil { - return nil, err - } - pages, err := api.PagesForPageSelection(ctx.PageCount, selectedPages, true, true) if err != nil { return nil, err @@ -165,10 +161,6 @@ func listFormFields(rs io.ReadSeeker, conf *model.Configuration) ([]string, erro return nil, err } - if err := ctx.EnsurePageCount(); err != nil { - return nil, err - } - return form.ListFormFields(ctx) } @@ -221,10 +213,6 @@ func listImages(rs io.ReadSeeker, selectedPages []string, conf *model.Configurat return nil, err } - if err := ctx.EnsurePageCount(); err != nil { - return nil, err - } - pages, err := api.PagesForPageSelection(ctx.PageCount, selectedPages, true, true) if err != nil { return nil, err diff --git a/pkg/pdfcpu/bookmark.go b/pkg/pdfcpu/bookmark.go index 1c42dea0..f2b0e702 100644 --- a/pkg/pdfcpu/bookmark.go +++ b/pkg/pdfcpu/bookmark.go @@ -598,7 +598,7 @@ func addBookmarkTree(ctx *model.Context, bmTree *BookmarkTree, replace bool) err return AddBookmarks(ctx, bmTree.Bookmarks, replace) } -func parseBookmarksFromJSON(ctx *model.Context, bb []byte) (*BookmarkTree, error) { +func parseBookmarksFromJSON(bb []byte) (*BookmarkTree, error) { if !json.Valid(bb) { return nil, errors.Errorf("pdfcpu: invalid JSON encoding detected.") @@ -621,7 +621,7 @@ func ImportBookmarks(ctx *model.Context, rd io.Reader, replace bool) (bool, erro return false, err } - bmTree, err := parseBookmarksFromJSON(ctx, buf.Bytes()) + bmTree, err := parseBookmarksFromJSON(buf.Bytes()) if err != nil { return false, err } diff --git a/pkg/pdfcpu/model/configuration.go b/pkg/pdfcpu/model/configuration.go index 85c3f3fc..316545b4 100644 --- a/pkg/pdfcpu/model/configuration.go +++ b/pkg/pdfcpu/model/configuration.go @@ -170,6 +170,9 @@ type Configuration struct { // Validate against ISO-32000: strict or relaxed. ValidationMode int + // Enable validation right before writing. + PostProcessValidate bool + // Check for broken links in LinkedAnnotations/URIActions. ValidateLinks bool diff --git a/pkg/pdfcpu/model/parseConfig.go b/pkg/pdfcpu/model/parseConfig.go index 55452cc3..d8a9aded 100644 --- a/pkg/pdfcpu/model/parseConfig.go +++ b/pkg/pdfcpu/model/parseConfig.go @@ -33,6 +33,7 @@ type configuration struct { Reader15 bool `yaml:"reader15"` DecodeAllStreams bool `yaml:"decodeAllStreams"` ValidationMode string `yaml:"validationMode"` + PostProcessValidate bool `yaml:"postProcessValidate"` Eol string `yaml:"eol"` WriteObjectStream bool `yaml:"writeObjectStream"` WriteXRefStream bool `yaml:"writeXRefStream"` @@ -68,6 +69,8 @@ func loadedConfig(c configuration, configPath string) *Configuration { conf.ValidationMode = ValidationRelaxed } + conf.PostProcessValidate = c.PostProcessValidate + switch c.Eol { case "EolLF": conf.Eol = types.EolLF diff --git a/pkg/pdfcpu/model/parseConfig_js.go b/pkg/pdfcpu/model/parseConfig_js.go index e29204f9..b34ebd97 100644 --- a/pkg/pdfcpu/model/parseConfig_js.go +++ b/pkg/pdfcpu/model/parseConfig_js.go @@ -55,6 +55,15 @@ func handleConfDecodeAllStreams(k, v string, c *Configuration) error { return nil } +func handleConfPostProcessValidate(k, v string, c *Configuration) error { + v = strings.ToLower(v) + if v != "true" && v != "false" { + return errors.Errorf("config key %s is boolean", k) + } + c.PostProcessValidate = v == "true" + return nil +} + func handleConfValidationMode(v string, c *Configuration) error { v1 := strings.ToLower(v) switch v1 { @@ -200,6 +209,9 @@ func parseKeysPart1(k, v string, c *Configuration) (bool, error) { case "validationMode": return true, handleConfValidationMode(v, c) + case "postProcessValidate": + return true, handleConfPostProcessValidate(k, v, c) + case "eol": return true, handleConfEol(v, c) @@ -208,7 +220,6 @@ func parseKeysPart1(k, v string, c *Configuration) (bool, error) { case "writeXRefStream": return true, handleConfWriteXRefStream(k, v, c) - } return false, nil diff --git a/pkg/pdfcpu/model/resources/config.yml b/pkg/pdfcpu/model/resources/config.yml index e840afe3..3a9aa5f5 100644 --- a/pkg/pdfcpu/model/resources/config.yml +++ b/pkg/pdfcpu/model/resources/config.yml @@ -14,6 +14,9 @@ decodeAllStreams: false # ValidationRelaxed, validationMode: ValidationRelaxed +# validate cross reference table right before writing +postProcessValidate: true + # eol for writing: # EolLF # EolCR diff --git a/pkg/pdfcpu/model/xreftable.go b/pkg/pdfcpu/model/xreftable.go index 10fa50a0..801aff63 100644 --- a/pkg/pdfcpu/model/xreftable.go +++ b/pkg/pdfcpu/model/xreftable.go @@ -2038,7 +2038,6 @@ func (xRefTable *XRefTable) PageNumber(pageObjNr int) (int, error) { } // EnsurePageCount evaluates the page count for xRefTable if necessary. -// Important when validation is turned off. func (xRefTable *XRefTable) EnsurePageCount() error { if xRefTable.PageCount > 0 { return nil @@ -2091,7 +2090,6 @@ func (xRefTable *XRefTable) collectPageBoundariesForPage(d types.Dict, pb []Page return errors.New("pdfcpu: collectMediaBoxesForPageTree: mediaBox is nil") } - //if inhCropBox != nil && inhCropBox.Rectangle != nil { if inhCropBox != nil { pb[p].Crop = &Box{Rect: inhCropBox, Inherited: true} } @@ -2245,59 +2243,15 @@ func (xRefTable *XRefTable) collectPageBoundariesForPageTree( return errors.New("pdfcpu: validatePagesDict: corrupt \"Kids\" entry") } - if err := xRefTable.collectPageBoundariesForPageTreeKids(kids, inhMediaBox, inhCropBox, pb, r, p, selectedPages); err != nil { - return err - } - - // // Iterate over page tree. - // for _, o := range kids { - - // if o == nil { - // continue - // } - - // // Dereference next page node dict. - // ir, ok := o.(types.IndirectRef) - // if !ok { - // return errors.Errorf("pdfcpu: collectMediaBoxesForPageTree: corrupt page node dict") - // } - - // pageNodeDict, err := xRefTable.DereferenceDict(ir) - // if err != nil { - // return err - // } - - // switch *pageNodeDict.Type() { - - // case "Pages": - // if err = xRefTable.collectPageBoundariesForPageTree(&ir, inhMediaBox, inhCropBox, pb, r, p, selectedPages); err != nil { - // return err - // } - - // case "Page": - // collect := len(selectedPages) == 0 - // if !collect { - // _, collect = selectedPages[(*p)+1] - // } - // if collect { - // if err = xRefTable.collectPageBoundariesForPageTree(&ir, inhMediaBox, inhCropBox, pb, r, p, selectedPages); err != nil { - // return err - // } - // } - // *p++ - // } - - // } - - return nil + return xRefTable.collectPageBoundariesForPageTreeKids(kids, inhMediaBox, inhCropBox, pb, r, p, selectedPages) } // PageBoundaries returns a sorted slice with page boundaries // for all pages sorted ascending by page number. func (xRefTable *XRefTable) PageBoundaries(selectedPages types.IntSet) ([]PageBoundaries, error) { - if err := xRefTable.EnsurePageCount(); err != nil { - return nil, err - } + // if err := xRefTable.EnsurePageCount(); err != nil { + // return nil, err + // } // Get an indirect reference to the page tree root dict. root, err := xRefTable.Pages() @@ -2741,7 +2695,10 @@ func (xRefTable *XRefTable) RemoveSignature() { d2 := xRefTable.Form delete(d2, "SigFlags") delete(d2, "XFA") - //delete(d2, "NeedAppearances") deprecated in PDF 2.0 + if xRefTable.Version() == V20 { + // deprecated in PDF 2.0 + delete(d2, "NeedAppearances") + } d1["AcroForm"] = d2 delete(d1, "Extensions") }