Author: ssteiner
Date: Mon Oct  3 09:41:41 2016
New Revision: 1763139

URL: http://svn.apache.org/viewvc?rev=1763139&view=rev
Log:
FOP-2654: IOException for PDF to PDF under low memory

Added:
    
xmlgraphics/fop-pdf-images/trunk/src/java/org/apache/fop/render/pdf/pdfbox/PDFBoxAdapterUtil.java
   (with props)
Modified:
    
xmlgraphics/fop-pdf-images/trunk/src/java/org/apache/fop/render/pdf/pdfbox/PDFBoxAdapter.java
    
xmlgraphics/fop-pdf-images/trunk/test/java/org/apache/fop/render/pdf/PDFBoxAdapterTestCase.java

Modified: 
xmlgraphics/fop-pdf-images/trunk/src/java/org/apache/fop/render/pdf/pdfbox/PDFBoxAdapter.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop-pdf-images/trunk/src/java/org/apache/fop/render/pdf/pdfbox/PDFBoxAdapter.java?rev=1763139&r1=1763138&r2=1763139&view=diff
==============================================================================
--- 
xmlgraphics/fop-pdf-images/trunk/src/java/org/apache/fop/render/pdf/pdfbox/PDFBoxAdapter.java
 (original)
+++ 
xmlgraphics/fop-pdf-images/trunk/src/java/org/apache/fop/render/pdf/pdfbox/PDFBoxAdapter.java
 Mon Oct  3 09:41:41 2016
@@ -62,7 +62,6 @@ import org.apache.pdfbox.pdmodel.common.
 import org.apache.pdfbox.pdmodel.common.PDRectangle;
 import org.apache.pdfbox.pdmodel.common.PDStream;
 
-import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotation;
 import org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm;
 
 import org.apache.fop.fonts.FontInfo;
@@ -184,7 +183,8 @@ public class PDFBoxAdapter {
         } else if (base instanceof COSDictionary) {
             return readCOSDictionary((COSDictionary) base, keyBase, exclude);
         } else if (base instanceof COSName) {
-            PDFName newName = new PDFName(((COSName)base).getName());
+            byte[] name = ((COSName)base).getName().getBytes("ISO-8859-1");
+            PDFName newName = new PDFName(new String(name, "ISO-8859-1"));
             return cacheClonedObject(keyBase, newName);
         } else if (base instanceof COSInteger) {
             PDFNumber number = new PDFNumber();
@@ -284,7 +284,7 @@ public class PDFBoxAdapter {
     }
 
     protected Object getCachedClone(Object base) throws IOException {
-        Object key = getBaseKey(base);
+        Object key = PDFBoxAdapterUtil.getBaseKey(base);
         Object o = clonedVersion.get(key);
         if (o == null) {
             return objectCache.get(key);
@@ -293,7 +293,7 @@ public class PDFBoxAdapter {
     }
 
     protected Object cacheClonedObject(Object base, Object cloned) throws 
IOException {
-        Object key = getBaseKey(base);
+        Object key = PDFBoxAdapterUtil.getBaseKey(base);
         if (key == null) {
             return cloned;
         }
@@ -312,35 +312,6 @@ public class PDFBoxAdapter {
         return cloned;
     }
 
-    private Object getBaseKey(Object base) throws IOException {
-        if (base instanceof COSObject) {
-            COSObject obj = (COSObject)base;
-            COSBase o = obj.getObject();
-            if (o instanceof COSStream) {
-                Integer hash = getStreamHash((COSStream) o);
-                if (hash != null) {
-                    return hash;
-                }
-            }
-            return obj.getObjectNumber() + " " + obj.getGenerationNumber();
-        } else if (base instanceof COSDictionary) {
-            return base;
-        } else {
-            return null;
-        }
-    }
-
-    private Integer getStreamHash(COSStream o) throws IOException {
-        for (COSBase x : o.getValues()) {
-            if (x instanceof COSObject || x instanceof COSDictionary) {
-                return null;
-            }
-        }
-        InputStream stream = o.getFilteredStream();
-        byte[] b = IOUtils.toByteArray(stream);
-        return Arrays.deepHashCode(new Object[]{b, o.toString()});
-    }
-
     private void transferDict(COSDictionary orgDict, PDFStream targetDict, Set 
filter) throws IOException {
         transferDict(orgDict, targetDict, filter, false);
     }
@@ -473,7 +444,7 @@ public class PDFBoxAdapter {
         atdoc.scale(-1, 1);
         atdoc.translate(-viewBox.getLowerLeftX(), -viewBox.getLowerLeftY());
 
-        rotate(rotation, viewBox, atdoc);
+        PDFBoxAdapterUtil.rotate(rotation, viewBox, atdoc);
 
         StringBuilder boxStr = new StringBuilder();
         boxStr.append(PDFNumber.doubleOut(mediaBox.getLowerLeftX())).append(' 
')
@@ -483,32 +454,6 @@ public class PDFBoxAdapter {
         return boxStr.toString() + 
IOUtils.toString(pdStream.createInputStream(null), "ISO-8859-1");
     }
 
-    private void rotate(int rotation, PDRectangle viewBox, AffineTransform 
atdoc) {
-        float x = viewBox.getWidth() + viewBox.getLowerLeftX();
-        float y = viewBox.getHeight() + viewBox.getLowerLeftY();
-        switch (rotation) {
-            case 90:
-                atdoc.scale(viewBox.getWidth() / viewBox.getHeight(), 
viewBox.getHeight() / viewBox.getWidth());
-                atdoc.translate(0, viewBox.getWidth());
-                atdoc.rotate(-Math.PI / 2.0);
-                atdoc.scale(viewBox.getWidth() / viewBox.getHeight(), 
viewBox.getHeight() / viewBox.getWidth());
-                break;
-            case 180:
-                atdoc.translate(x, y);
-                atdoc.rotate(-Math.PI);
-                atdoc.translate(-viewBox.getLowerLeftX(), 
-viewBox.getLowerLeftY());
-                break;
-            case 270:
-                atdoc.translate(viewBox.getLowerLeftX(), y);
-                atdoc.rotate(Math.toRadians(270 + 180));
-                atdoc.translate(-x, -y);
-                break;
-            default:
-                //no additional transformations necessary
-                break;
-        }
-    }
-
     private PDStream getContents(PDPage page) throws IOException {
         PDStream pdStream = new PDStream(new COSStream());
         OutputStream os = pdStream.createOutputStream();
@@ -621,7 +566,7 @@ public class PDFBoxAdapter {
             return;
         }
 
-        moveAnnotations(page, pageAnnotations, at);
+        PDFBoxAdapterUtil.moveAnnotations(page, pageAnnotations, at);
 
         //Pseudo-cache the target page in place of the original source page.
         //This essentially replaces the original page reference with the 
target page.
@@ -683,25 +628,6 @@ public class PDFBoxAdapter {
         }
     }
 
-    private void updateAnnotationLink(PDFDictionary clonedAnnot) {
-        Object a = clonedAnnot.get("A");
-        if (a instanceof PDFDictionary) {
-            PDFDictionary annot = (PDFDictionary) a;
-            Object oldarrayObj = annot.get("D");
-            if (oldarrayObj instanceof PDFArray) {
-                PDFArray oldarray = (PDFArray) oldarrayObj;
-                Object newarrayObj = oldarray.get(0);
-                if (newarrayObj instanceof PDFArray) {
-                    PDFArray newarray = (PDFArray) newarrayObj;
-                    for (int i = 1; i < oldarray.length(); i++) {
-                        newarray.add(oldarray.get(i));
-                    }
-                    annot.put("D", oldarray.get(0));
-                }
-            }
-        }
-    }
-
     private Set<COSObject> copyAnnotations(PDPage page) throws IOException {
         COSArray annots = (COSArray) 
page.getCOSObject().getDictionaryObject(COSName.ANNOTS);
         Set<COSObject> fields = Collections.emptySet();
@@ -729,7 +655,7 @@ public class PDFBoxAdapter {
                 PDFObject clonedAnnot = (PDFObject) 
cloneForNewDocument(annot1, annot1, exclude);
                 if (clonedAnnot instanceof PDFDictionary) {
                     clonedAnnot.setParent(targetPage);
-                    updateAnnotationLink((PDFDictionary) clonedAnnot);
+                    PDFBoxAdapterUtil.updateAnnotationLink((PDFDictionary) 
clonedAnnot);
                 }
                 targetPage.addAnnotation(clonedAnnot);
             }
@@ -737,35 +663,6 @@ public class PDFBoxAdapter {
         return fields;
     }
 
-    private void moveAnnotations(PDPage page, List pageAnnotations, 
AffineTransform at) {
-        PDRectangle mediaBox = page.getMediaBox();
-        PDRectangle cropBox = page.getCropBox();
-        PDRectangle viewBox = cropBox != null ? cropBox : mediaBox;
-        for (Object obj : pageAnnotations) {
-            PDAnnotation annot = (PDAnnotation)obj;
-            PDRectangle rect = annot.getRectangle();
-            float translateX = (float) (at.getTranslateX() - 
viewBox.getLowerLeftX());
-            float translateY = (float) (at.getTranslateY() - 
viewBox.getLowerLeftY());
-            if (rect != null) {
-                rect.setUpperRightX(rect.getUpperRightX() + translateX);
-                rect.setLowerLeftX(rect.getLowerLeftX() + translateX);
-                rect.setUpperRightY(rect.getUpperRightY() + translateY);
-                rect.setLowerLeftY(rect.getLowerLeftY() + translateY);
-                annot.setRectangle(rect);
-            }
-//            COSArray vertices = (COSArray) 
annot.getCOSObject().getDictionaryObject("Vertices");
-//            if (vertices != null) {
-//                Iterator iter = vertices.iterator();
-//                while (iter.hasNext()) {
-//                    COSFloat x = (COSFloat) iter.next();
-//                    COSFloat y = (COSFloat) iter.next();
-//                    x.setValue(x.floatValue() + translateX);
-//                    y.setValue(y.floatValue() + translateY);
-//                }
-//            }
-        }
-    }
-
     static class CompareFields implements Comparator<COSObject>, Serializable {
         private static final long serialVersionUID = -6081505461660440801L;
 

Added: 
xmlgraphics/fop-pdf-images/trunk/src/java/org/apache/fop/render/pdf/pdfbox/PDFBoxAdapterUtil.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop-pdf-images/trunk/src/java/org/apache/fop/render/pdf/pdfbox/PDFBoxAdapterUtil.java?rev=1763139&view=auto
==============================================================================
--- 
xmlgraphics/fop-pdf-images/trunk/src/java/org/apache/fop/render/pdf/pdfbox/PDFBoxAdapterUtil.java
 (added)
+++ 
xmlgraphics/fop-pdf-images/trunk/src/java/org/apache/fop/render/pdf/pdfbox/PDFBoxAdapterUtil.java
 Mon Oct  3 09:41:41 2016
@@ -0,0 +1,185 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+package org.apache.fop.render.pdf.pdfbox;
+
+import java.awt.geom.AffineTransform;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.pdfbox.cos.COSBase;
+import org.apache.pdfbox.cos.COSDictionary;
+import org.apache.pdfbox.cos.COSName;
+import org.apache.pdfbox.cos.COSObject;
+import org.apache.pdfbox.cos.COSStream;
+import org.apache.pdfbox.pdmodel.PDPage;
+import org.apache.pdfbox.pdmodel.common.PDRectangle;
+import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotation;
+
+import org.apache.fop.pdf.PDFArray;
+import org.apache.fop.pdf.PDFDictionary;
+
+public final class PDFBoxAdapterUtil {
+    private PDFBoxAdapterUtil() {
+    }
+
+    private static Integer getStreamHash(COSStream o) throws IOException {
+        for (COSBase x : o.getValues()) {
+            if (x instanceof COSObject || x instanceof COSDictionary) {
+                return null;
+            }
+        }
+        InputStream stream = o.getFilteredStream();
+        byte[] b = IOUtils.toByteArray(stream);
+        return Arrays.deepHashCode(new Object[]{b, o.toString()});
+    }
+
+    private static String getDictionaryHash(COSBase base) throws IOException {
+        return getDictionaryHash(base, new ArrayList<COSBase>());
+    }
+
+    private static String getDictionaryHash(COSBase base, List<COSBase> objs) 
throws IOException {
+        if (base == null) {
+            return "null";
+        }
+        if (objs.contains(base)) {
+            return String.valueOf(base.hashCode());
+        }
+        objs.add(base);
+        if (base instanceof COSDictionary) {
+            StringBuilder sb = new StringBuilder();
+            sb.append("COSDictionary{");
+            for (Map.Entry<COSName, COSBase> x : ((COSDictionary) 
base).entrySet()) {
+                sb.append(x.getKey());
+                sb.append(":");
+                sb.append(getDictionaryHash(x.getValue(), objs));
+                sb.append(";");
+            }
+            sb.append("}");
+            if (base instanceof COSStream) {
+                InputStream stream = ((COSStream)base).getFilteredStream();
+                byte[] b = IOUtils.toByteArray(stream);
+                sb.append("COSStream{").append(Arrays.hashCode(b)).append("}");
+            }
+            return sb.toString();
+        } else if (base instanceof COSObject) {
+            COSObject obj = (COSObject) base;
+            return "COSObject{" + getDictionaryHash(obj.getObject(), objs) + 
"}";
+        } else {
+            return base.toString();
+        }
+    }
+
+    protected static Object getBaseKey(Object base) throws IOException {
+        if (base instanceof COSObject) {
+            COSObject obj = (COSObject)base;
+            COSBase o = obj.getObject();
+            if (o instanceof COSStream) {
+                Integer hash = PDFBoxAdapterUtil.getStreamHash((COSStream) o);
+                if (hash != null) {
+                    return hash;
+                }
+            }
+            return obj.getObjectNumber() + " " + obj.getGenerationNumber();
+        }
+        if (base instanceof COSDictionary) {
+            String dict = PDFBoxAdapterUtil.getDictionaryHash((COSBase) base);
+            return String.valueOf(dict.hashCode());
+        }
+        return null;
+    }
+
+    protected static void rotate(int rotation, PDRectangle viewBox, 
AffineTransform atdoc) {
+        float x = viewBox.getWidth() + viewBox.getLowerLeftX();
+        float y = viewBox.getHeight() + viewBox.getLowerLeftY();
+        switch (rotation) {
+            case 90:
+                atdoc.scale(viewBox.getWidth() / viewBox.getHeight(), 
viewBox.getHeight() / viewBox.getWidth());
+                atdoc.translate(0, viewBox.getWidth());
+                atdoc.rotate(-Math.PI / 2.0);
+                atdoc.scale(viewBox.getWidth() / viewBox.getHeight(), 
viewBox.getHeight() / viewBox.getWidth());
+                break;
+            case 180:
+                atdoc.translate(x, y);
+                atdoc.rotate(-Math.PI);
+                atdoc.translate(-viewBox.getLowerLeftX(), 
-viewBox.getLowerLeftY());
+                break;
+            case 270:
+                atdoc.translate(viewBox.getLowerLeftX(), y);
+                atdoc.rotate(Math.toRadians(270 + 180));
+                atdoc.translate(-x, -y);
+                break;
+            default:
+                //no additional transformations necessary
+                break;
+        }
+    }
+
+    protected static void updateAnnotationLink(PDFDictionary clonedAnnot) {
+        Object a = clonedAnnot.get("A");
+        if (a instanceof PDFDictionary) {
+            PDFDictionary annot = (PDFDictionary) a;
+            Object oldarrayObj = annot.get("D");
+            if (oldarrayObj instanceof PDFArray) {
+                PDFArray oldarray = (PDFArray) oldarrayObj;
+                Object newarrayObj = oldarray.get(0);
+                if (newarrayObj instanceof PDFArray) {
+                    PDFArray newarray = (PDFArray) newarrayObj;
+                    for (int i = 1; i < oldarray.length(); i++) {
+                        newarray.add(oldarray.get(i));
+                    }
+                    annot.put("D", oldarray.get(0));
+                }
+            }
+        }
+    }
+
+    protected static void moveAnnotations(PDPage page, List pageAnnotations, 
AffineTransform at) {
+        PDRectangle mediaBox = page.getMediaBox();
+        PDRectangle cropBox = page.getCropBox();
+        PDRectangle viewBox = cropBox != null ? cropBox : mediaBox;
+        for (Object obj : pageAnnotations) {
+            PDAnnotation annot = (PDAnnotation)obj;
+            PDRectangle rect = annot.getRectangle();
+            float translateX = (float) (at.getTranslateX() - 
viewBox.getLowerLeftX());
+            float translateY = (float) (at.getTranslateY() - 
viewBox.getLowerLeftY());
+            if (rect != null) {
+                rect.setUpperRightX(rect.getUpperRightX() + translateX);
+                rect.setLowerLeftX(rect.getLowerLeftX() + translateX);
+                rect.setUpperRightY(rect.getUpperRightY() + translateY);
+                rect.setLowerLeftY(rect.getLowerLeftY() + translateY);
+                annot.setRectangle(rect);
+            }
+//            COSArray vertices = (COSArray) 
annot.getCOSObject().getDictionaryObject("Vertices");
+//            if (vertices != null) {
+//                Iterator iter = vertices.iterator();
+//                while (iter.hasNext()) {
+//                    COSFloat x = (COSFloat) iter.next();
+//                    COSFloat y = (COSFloat) iter.next();
+//                    x.setValue(x.floatValue() + translateX);
+//                    y.setValue(y.floatValue() + translateY);
+//                }
+//            }
+        }
+    }
+}

Propchange: 
xmlgraphics/fop-pdf-images/trunk/src/java/org/apache/fop/render/pdf/pdfbox/PDFBoxAdapterUtil.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: 
xmlgraphics/fop-pdf-images/trunk/test/java/org/apache/fop/render/pdf/PDFBoxAdapterTestCase.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop-pdf-images/trunk/test/java/org/apache/fop/render/pdf/PDFBoxAdapterTestCase.java?rev=1763139&r1=1763138&r2=1763139&view=diff
==============================================================================
--- 
xmlgraphics/fop-pdf-images/trunk/test/java/org/apache/fop/render/pdf/PDFBoxAdapterTestCase.java
 (original)
+++ 
xmlgraphics/fop-pdf-images/trunk/test/java/org/apache/fop/render/pdf/PDFBoxAdapterTestCase.java
 Mon Oct  3 09:41:41 2016
@@ -66,6 +66,7 @@ import org.apache.fop.fonts.MultiByteFon
 import org.apache.fop.fonts.Typeface;
 import org.apache.fop.pdf.PDFAnnotList;
 import org.apache.fop.pdf.PDFArray;
+import org.apache.fop.pdf.PDFDictionary;
 import org.apache.fop.pdf.PDFDocument;
 import org.apache.fop.pdf.PDFFilterList;
 import org.apache.fop.pdf.PDFGState;
@@ -520,8 +521,9 @@ public class PDFBoxAdapterTestCase {
         pdfdoc.assignObjectNumber(pdfpage);
         pdfpage.setDocument(pdfdoc);
         Map<Object, Object> pdfCache = new HashMap<Object, Object>();
+        Map<Object, Object> objectCachePerFile = new HashMap<Object, Object>();
         PDFBoxAdapter adapter = new PDFBoxAdapter(
-                pdfpage, new HashMap<Object, Object>(), new HashMap<Integer, 
PDFArray>(), pdfCache);
+                pdfpage, objectCachePerFile, new HashMap<Integer, PDFArray>(), 
pdfCache);
         PDDocument doc = PDDocument.load(new File(LOOP));
         PDPage page = doc.getDocumentCatalog().getPages().get(0);
         adapter.createStreamFromPDFBoxPage(doc, page, "key", new 
AffineTransform(), null, new Rectangle());
@@ -529,6 +531,14 @@ public class PDFBoxAdapterTestCase {
 
         Object item = pdfCache.values().iterator().next();
         Assert.assertEquals(item.getClass(), PDFStream.class);
+        item = pdfCache.keySet().iterator().next();
+        Assert.assertEquals(item.getClass(), Integer.class);
         Assert.assertEquals(pdfCache.size(), 11);
+
+        item = objectCachePerFile.values().iterator().next();
+        Assert.assertEquals(item.getClass(), PDFDictionary.class);
+        item = objectCachePerFile.keySet().iterator().next();
+        Assert.assertEquals(item.getClass(), String.class);
+        Assert.assertEquals(objectCachePerFile.size(), 45);
     }
 }



---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to