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]