Xref stream progress
This commit is contained in:
@@ -6,39 +6,42 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func (context *SignContext) writeTrailer() error {
|
func (context *SignContext) writeTrailer() error {
|
||||||
trailer_length := context.PDFReader.XrefInformation.IncludingTrailerEndPos - context.PDFReader.XrefInformation.EndPos
|
|
||||||
|
|
||||||
// Read the trailer so we can replace the size.
|
if context.PDFReader.XrefInformation.Type == "table" {
|
||||||
context.InputFile.Seek(context.PDFReader.XrefInformation.EndPos+1, 0)
|
trailer_length := context.PDFReader.XrefInformation.IncludingTrailerEndPos - context.PDFReader.XrefInformation.EndPos
|
||||||
trailer_buf := make([]byte, trailer_length)
|
|
||||||
if _, err := context.InputFile.Read(trailer_buf); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
root_string := "Root " + context.CatalogData.RootString
|
// Read the trailer so we can replace the size.
|
||||||
new_root := "Root " + strconv.FormatInt(int64(context.CatalogData.ObjectId), 10) + " 0 R"
|
context.InputFile.Seek(context.PDFReader.XrefInformation.EndPos+1, 0)
|
||||||
|
trailer_buf := make([]byte, trailer_length)
|
||||||
|
if _, err := context.InputFile.Read(trailer_buf); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
size_string := "Size " + strconv.FormatInt(context.PDFReader.XrefInformation.ItemCount, 10)
|
root_string := "Root " + context.CatalogData.RootString
|
||||||
new_size := "Size " + strconv.FormatInt(context.PDFReader.XrefInformation.ItemCount+4, 10)
|
new_root := "Root " + strconv.FormatInt(int64(context.CatalogData.ObjectId), 10) + " 0 R"
|
||||||
|
|
||||||
info := context.PDFReader.Trailer().Key("Info")
|
size_string := "Size " + strconv.FormatInt(context.PDFReader.XrefInformation.ItemCount, 10)
|
||||||
infoPtr := info.GetPtr()
|
new_size := "Size " + strconv.FormatInt(context.PDFReader.XrefInformation.ItemCount+4, 10)
|
||||||
|
|
||||||
info_string := "Info " + strconv.Itoa(int(infoPtr.GetID())) + " " + strconv.Itoa(int(infoPtr.GetGen())) + " R"
|
info := context.PDFReader.Trailer().Key("Info")
|
||||||
new_info := "Info " + strconv.FormatInt(int64(context.InfoData.ObjectId), 10) + " 0 R"
|
infoPtr := info.GetPtr()
|
||||||
|
|
||||||
trailer_string := string(trailer_buf)
|
info_string := "Info " + strconv.Itoa(int(infoPtr.GetID())) + " " + strconv.Itoa(int(infoPtr.GetGen())) + " R"
|
||||||
trailer_string = strings.Replace(trailer_string, root_string, new_root, -1)
|
new_info := "Info " + strconv.FormatInt(int64(context.InfoData.ObjectId), 10) + " 0 R"
|
||||||
trailer_string = strings.Replace(trailer_string, size_string, new_size, -1)
|
|
||||||
trailer_string = strings.Replace(trailer_string, info_string, new_info, -1)
|
|
||||||
|
|
||||||
// Write the new trailer.
|
trailer_string := string(trailer_buf)
|
||||||
if _, err := context.OutputFile.Write([]byte(trailer_string)); err != nil {
|
trailer_string = strings.Replace(trailer_string, root_string, new_root, -1)
|
||||||
return err
|
trailer_string = strings.Replace(trailer_string, size_string, new_size, -1)
|
||||||
|
trailer_string = strings.Replace(trailer_string, info_string, new_info, -1)
|
||||||
|
|
||||||
|
// Write the new trailer.
|
||||||
|
if _, err := context.OutputFile.Write([]byte(trailer_string)); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write the new xref start position.
|
// Write the new xref start position.
|
||||||
if _, err := context.OutputFile.Write([]byte(strconv.FormatInt(context.NewXrefStart, 10) + "\n")); err != nil {
|
if _, err := context.OutputFile.Write([]byte("\nstartxref\n" + strconv.FormatInt(context.NewXrefStart, 10) + "\n")); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -3,16 +3,21 @@ package sign
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"encoding/hex"
|
||||||
|
"compress/zlib"
|
||||||
|
"bytes"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (context *SignContext) writeXref() error {
|
func (context *SignContext) writeXref() error {
|
||||||
|
|
||||||
// @todo: support stream xref.
|
|
||||||
|
|
||||||
if context.PDFReader.XrefInformation.Type == "table" {
|
if context.PDFReader.XrefInformation.Type == "table" {
|
||||||
if err := context.writeXrefTable(); err != nil {
|
if err := context.writeXrefTable(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
} else if context.PDFReader.XrefInformation.Type == "stream" {
|
||||||
|
if err := context.writeXrefStream(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return errors.New("Unkwn xref type: " + context.PDFReader.XrefInformation.Type)
|
return errors.New("Unkwn xref type: " + context.PDFReader.XrefInformation.Type)
|
||||||
}
|
}
|
||||||
@@ -71,3 +76,76 @@ func (context *SignContext) writeXrefTable() error {
|
|||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (context *SignContext) writeXrefStream() error {
|
||||||
|
// @todo: DO NOT FORGET TO ADD SELF REFERENCE!!!
|
||||||
|
// @todo: fix format (columns) for stream
|
||||||
|
// @todo: add PNG-Up support.
|
||||||
|
var streamBytes bytes.Buffer
|
||||||
|
w := zlib.NewWriter(&streamBytes)
|
||||||
|
|
||||||
|
// Create the new catalog xref line.
|
||||||
|
visual_signature_object_start_position := strconv.FormatInt(context.Filesize, 10)
|
||||||
|
visual_signature_xref_line := leftPad(visual_signature_object_start_position, "0", 10-len(visual_signature_object_start_position)) + " 00000 n \n"
|
||||||
|
|
||||||
|
// Write the new catalog xref line.
|
||||||
|
if _, err := w.Write([]byte(visual_signature_xref_line)); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the new catalog xref line.
|
||||||
|
catalog_object_start_position := strconv.FormatInt(context.Filesize+context.VisualSignData.Length, 10)
|
||||||
|
catalog_xref_line := leftPad(catalog_object_start_position, "0", 10-len(catalog_object_start_position)) + " 00000 n \n"
|
||||||
|
|
||||||
|
// Write the new catalog xref line.
|
||||||
|
if _, err := w.Write([]byte(catalog_xref_line)); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the new signature xref line.
|
||||||
|
info_object_start_position := strconv.FormatInt(context.Filesize+context.VisualSignData.Length+context.CatalogData.Length, 10)
|
||||||
|
info_xref_line := leftPad(info_object_start_position, "0", 10-len(info_object_start_position)) + " 00000 n \n"
|
||||||
|
|
||||||
|
// Write the new signature xref line.
|
||||||
|
if _, err := w.Write([]byte(info_xref_line)); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the new signature xref line.
|
||||||
|
signature_object_start_position := strconv.FormatInt(context.Filesize+context.VisualSignData.Length+context.CatalogData.Length+context.InfoData.Length, 10)
|
||||||
|
signature_xref_line := leftPad(signature_object_start_position, "0", 10-len(signature_object_start_position)) + " 00000 n \n"
|
||||||
|
|
||||||
|
// Write the new signature xref line.
|
||||||
|
if _, err := w.Write([]byte(signature_xref_line)); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
w.Close()
|
||||||
|
|
||||||
|
new_info := "Info " + strconv.FormatInt(int64(context.InfoData.ObjectId), 10) + " 0 R"
|
||||||
|
new_root := "Root " + strconv.FormatInt(int64(context.CatalogData.ObjectId), 10) + " 0 R"
|
||||||
|
|
||||||
|
id := context.PDFReader.Trailer().Key("ID")
|
||||||
|
|
||||||
|
id0 := hex.EncodeToString([]byte(id.Index(0).RawString()))
|
||||||
|
id1 := hex.EncodeToString([]byte(id.Index(0).RawString()))
|
||||||
|
|
||||||
|
new_xref := strconv.Itoa(int(context.SignData.ObjectId + 1)) + " 0 obj\n"
|
||||||
|
new_xref += "<< /Type /XRef /Length " + strconv.Itoa(len(streamBytes.Bytes())) + " /Filter /FlateDecode /DecodeParms << /Columns 5 /Predictor 12 >> /W [ 1 3 1 ] /Prev " + strconv.FormatInt(context.PDFReader.XrefInformation.StartPos, 10) + " /Size " + strconv.FormatInt(context.PDFReader.XrefInformation.ItemCount+5, 10) + " /Index [ 5 " + strconv.FormatInt(context.PDFReader.XrefInformation.ItemCount, 10) + " ] /" + new_info + " /" + new_root + " /ID [<" + id0 + "><" + id1 + ">] >>\n"
|
||||||
|
if _, err := context.OutputFile.Write([]byte(new_xref)); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := context.OutputFile.Write([]byte("stream\n")); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := context.OutputFile.Write(streamBytes.Bytes()); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := context.OutputFile.Write([]byte("\nendstream\n")); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user