You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pdfbox.apache.org by le...@apache.org on 2015/11/23 19:15:27 UTC

svn commit: r1715907 - in /pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox: pdfwriter/COSWriter.java pdmodel/PDDocument.java

Author: lehmi
Date: Mon Nov 23 18:15:26 2015
New Revision: 1715907

URL: http://svn.apache.org/viewvc?rev=1715907&view=rev
Log:
PDFBOX-3115: reduce memory footprint during signing a pdf

Modified:
    pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdfwriter/COSWriter.java
    pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/PDDocument.java

Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdfwriter/COSWriter.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdfwriter/COSWriter.java?rev=1715907&r1=1715906&r2=1715907&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdfwriter/COSWriter.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdfwriter/COSWriter.java Mon Nov 23 18:15:26 2015
@@ -58,6 +58,9 @@ import org.apache.pdfbox.cos.COSString;
 import org.apache.pdfbox.cos.COSUpdateInfo;
 import org.apache.pdfbox.cos.ICOSVisitor;
 import org.apache.pdfbox.io.IOUtils;
+import org.apache.pdfbox.io.RandomAccessBuffer;
+import org.apache.pdfbox.io.RandomAccessInputStream;
+import org.apache.pdfbox.io.RandomAccessRead;
 import org.apache.pdfbox.pdfparser.PDFXRefStream;
 import org.apache.pdfbox.pdmodel.PDDocument;
 import org.apache.pdfbox.pdmodel.encryption.SecurityHandler;
@@ -210,7 +213,8 @@ public class COSWriter implements ICOSVi
     private boolean reachedSignature = false;
     private long signatureOffset, signatureLength;
     private long byteRangeOffset, byteRangeLength;
-    private InputStream incrementalInput;
+    private RandomAccessRead incrementalInput;
+    private RandomAccessRead tempIncInput;
     private OutputStream incrementalOutput;
     private SignatureInterface signatureInterface;
 
@@ -235,16 +239,36 @@ public class COSWriter implements ICOSVi
      * @param inputStream input stream containing source PDF data
      * 
      * @throws IOException if something went wrong
+     * @deprecated Use {@link #COSWriter(OutputStream, RandomAccessRead)} instead
      */
     public COSWriter(OutputStream outputStream, InputStream inputStream) throws IOException
     {
         super();
+        tempIncInput = new RandomAccessBuffer(inputStream);
+        initWriter(outputStream, tempIncInput);
+    }
 
+    /**
+     * COSWriter constructor for incremental updates. 
+     *
+     * @param outputStream output stream where the new PDF data will be written
+     * @param inputData random access read containing source PDF data
+     * 
+     * @throws IOException if something went wrong
+     */
+    public COSWriter(OutputStream outputStream, RandomAccessRead inputData) throws IOException
+    {
+        super();
+        initWriter(outputStream, inputData);
+    }
+
+    private void initWriter(OutputStream outputStream, RandomAccessRead inputData) throws IOException
+    {
         // write to buffer instead of output
         setOutput(new ByteArrayOutputStream());
-        setStandardOutput(new COSStandardOutputStream(output, inputStream.available()));
+        setStandardOutput(new COSStandardOutputStream(output, (int)inputData.length()));
 
-        incrementalInput = inputStream;
+        incrementalInput = inputData;
         incrementalOutput = outputStream;
         incrementalUpdate = true;
 
@@ -320,6 +344,10 @@ public class COSWriter implements ICOSVi
         {
             incrementalOutput.close();
         }
+        if (tempIncInput != null)
+        {
+            incrementalOutput.close();
+        }
     }
 
     /**
@@ -688,7 +716,7 @@ public class COSWriter implements ICOSVi
         }
 
         // calculate the ByteRange values
-        long inLength = incrementalInput.available();
+        long inLength = incrementalInput.length();
         long beforeLength = signatureOffset;
         long afterOffset = signatureOffset + signatureLength;
         long afterLength = getStandardOutput().getPos() - (inLength + signatureLength) - (signatureOffset - inLength);
@@ -718,9 +746,6 @@ public class COSWriter implements ICOSVi
             }
         }
 
-        // get the input PDF bytes
-        byte[] inputBytes = IOUtils.toByteArray(incrementalInput);
-
         // get only the incremental bytes to be signed (includes /ByteRange but not /Contents)
         byte[] signBuffer = new byte[buffer.length - (int)signatureLength];
         int bufSignatureOffset = (int)(signatureOffset - inLength);
@@ -728,7 +753,7 @@ public class COSWriter implements ICOSVi
         System.arraycopy(buffer, bufSignatureOffset + (int)signatureLength,
                          signBuffer, bufSignatureOffset, buffer.length - bufSignatureOffset - (int)signatureLength);
 
-        SequenceInputStream signStream = new SequenceInputStream(new ByteArrayInputStream(inputBytes),
+        SequenceInputStream signStream = new SequenceInputStream(new RandomAccessInputStream(incrementalInput),
                 new ByteArrayInputStream(signBuffer));
 
         // sign the bytes
@@ -745,10 +770,10 @@ public class COSWriter implements ICOSVi
         System.arraycopy(signatureBytes, 0, buffer, bufSignatureOffset + 1, signatureBytes.length);
 
         // write the data to the incremental output stream
-        incrementalOutput.write(inputBytes);
+        IOUtils.copy(new RandomAccessInputStream(incrementalInput), incrementalOutput);
         incrementalOutput.write(buffer);
     }
-    
+
     private void writeXrefRange(long x, long y) throws IOException
     {
         getStandardOutput().write(String.valueOf(x).getBytes(Charsets.ISO_8859_1));

Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/PDDocument.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/PDDocument.java?rev=1715907&r1=1715906&r2=1715907&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/PDDocument.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/PDDocument.java Mon Nov 23 18:15:26 2015
@@ -1126,11 +1126,10 @@ public class PDDocument implements Close
      */
     public void saveIncremental(OutputStream output) throws IOException
     {
-        InputStream input = new RandomAccessInputStream(pdfSource);
         COSWriter writer = null;
         try
         {
-            writer = new COSWriter(output, input);
+            writer = new COSWriter(output, pdfSource);
             writer.write(this, signInterface);
             writer.close();
         }