You are viewing a plain text version of this content. The canonical link for it is here.
Posted to fop-commits@xmlgraphics.apache.org by ss...@apache.org on 2016/09/06 08:45:53 UTC
svn commit: r1759382 - in /xmlgraphics/fop-pdf-images/trunk:
src/java/org/apache/fop/render/pdf/pdfbox/AbstractPDFBoxHandler.java
src/java/org/apache/fop/render/pdf/pdfbox/PDFBoxAdapter.java
test/java/org/apache/fop/render/pdf/PDFBoxAdapterTestCase.java
Author: ssteiner
Date: Tue Sep 6 08:45:52 2016
New Revision: 1759382
URL: http://svn.apache.org/viewvc?rev=1759382&view=rev
Log:
FOP-2645: Deduplicate PDF streams
Modified:
xmlgraphics/fop-pdf-images/trunk/src/java/org/apache/fop/render/pdf/pdfbox/AbstractPDFBoxHandler.java
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/AbstractPDFBoxHandler.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop-pdf-images/trunk/src/java/org/apache/fop/render/pdf/pdfbox/AbstractPDFBoxHandler.java?rev=1759382&r1=1759381&r2=1759382&view=diff
==============================================================================
--- xmlgraphics/fop-pdf-images/trunk/src/java/org/apache/fop/render/pdf/pdfbox/AbstractPDFBoxHandler.java (original)
+++ xmlgraphics/fop-pdf-images/trunk/src/java/org/apache/fop/render/pdf/pdfbox/AbstractPDFBoxHandler.java Tue Sep 6 08:45:52 2016
@@ -91,7 +91,7 @@ public abstract class AbstractPDFBoxHand
getEventProducer(eventBroadcaster).pdfXActive(this);
}
- Map<Object, Object> objectCache = getObjectCache(originalImageUri, userAgent);
+ Map<Object, Object> objectCachePerFile = getObjectCache(getImagePath(originalImageUri), userAgent);
PDPage page = pddoc.getDocumentCatalog().getPages().get(selectedPage);
@@ -102,7 +102,9 @@ public abstract class AbstractPDFBoxHand
targetPage.put("Resources", res);
}
- PDFBoxAdapter adapter = new PDFBoxAdapter(targetPage, objectCache, pageNumbers);
+ Map<Object, Object> objectCache = getObjectCache(getClass().getName(), userAgent);
+ PDFBoxAdapter adapter =
+ new PDFBoxAdapter(targetPage, objectCachePerFile, pageNumbers, objectCache);
if (handler != null) {
adapter.setCurrentMCID(handler.getPageParentTree().length());
}
@@ -115,9 +117,8 @@ public abstract class AbstractPDFBoxHand
return stream;
}
- private Map<Object, Object> getObjectCache(String originalImageUri, FOUserAgent userAgent) {
+ private Map<Object, Object> getObjectCache(String path, FOUserAgent userAgent) {
SoftMapCache objectCache = userAgent.getPDFObjectCache();
- String path = getImagePath(originalImageUri);
if (objectCache.get(path) == null) {
objectCache.put(path, new HashMap<Object, Object>());
}
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=1759382&r1=1759381&r2=1759382&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 Tue Sep 6 08:45:52 2016
@@ -93,7 +93,8 @@ public class PDFBoxAdapter {
private final PDFPage targetPage;
private final PDFDocument pdfDoc;
- private final Map clonedVersion;
+ private final Map<Object, Object> clonedVersion;
+ private final Map<Object, Object> objectCache;
private Map<COSName, String> newXObj = new HashMap<COSName, String>();
private Map<Integer, PDFArray> pageNumbers;
private Collection<String> parentFonts = new ArrayList<String>();
@@ -103,14 +104,21 @@ public class PDFBoxAdapter {
/**
* Creates a new PDFBoxAdapter.
* @param targetPage The target FOP PDF page object
- * @param objectCache the object cache for reusing objects shared by multiple pages.
+ * @param objectCachePerFile the object cache for reusing objects shared by multiple pages.
* @param pageNumbers references to page object numbers
*/
- public PDFBoxAdapter(PDFPage targetPage, Map objectCache, Map<Integer, PDFArray> pageNumbers) {
+ public PDFBoxAdapter(PDFPage targetPage, Map<Object, Object> objectCachePerFile,
+ Map<Integer, PDFArray> pageNumbers) {
+ this(targetPage, objectCachePerFile, pageNumbers, new HashMap<Object, Object>());
+ }
+
+ public PDFBoxAdapter(PDFPage targetPage, Map<Object, Object> objectCachePerFile,
+ Map<Integer, PDFArray> pageNumbers, Map<Object, Object> objectCache) {
this.targetPage = targetPage;
this.pdfDoc = this.targetPage.getDocument();
- this.clonedVersion = objectCache;
+ this.clonedVersion = objectCachePerFile;
this.pageNumbers = pageNumbers;
+ this.objectCache = objectCache;
}
public PDFPage getTargetPage() {
@@ -239,7 +247,7 @@ public class PDFBoxAdapter {
return obj;
}
- private Object readCOSString(COSString string, Object keyBase) {
+ private Object readCOSString(COSString string, Object keyBase) throws IOException {
//retval = ((COSString)base).getString(); //this is unsafe for binary content
byte[] bytes = string.getBytes();
//Be on the safe side and use the byte array to avoid encoding problems
@@ -275,11 +283,16 @@ public class PDFBoxAdapter {
return cacheClonedObject(keyBase, stream);
}
- protected Object getCachedClone(Object base) {
- return clonedVersion.get(getBaseKey(base));
+ protected Object getCachedClone(Object base) throws IOException {
+ Object key = getBaseKey(base);
+ Object o = clonedVersion.get(key);
+ if (o == null) {
+ return objectCache.get(key);
+ }
+ return o;
}
- protected Object cacheClonedObject(Object base, Object cloned) {
+ protected Object cacheClonedObject(Object base, Object cloned) throws IOException {
Object key = getBaseKey(base);
if (key == null) {
return cloned;
@@ -293,12 +306,22 @@ public class PDFBoxAdapter {
}
}
clonedVersion.put(key, cloned);
+ if (key instanceof Integer) {
+ objectCache.put(key, cloned);
+ }
return cloned;
}
- private Object getBaseKey(Object base) {
+ 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;
@@ -307,6 +330,17 @@ public class PDFBoxAdapter {
}
}
+ 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);
}
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=1759382&r1=1759381&r2=1759382&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 Tue Sep 6 08:45:52 2016
@@ -71,6 +71,7 @@ import org.apache.fop.pdf.PDFFilterList;
import org.apache.fop.pdf.PDFGState;
import org.apache.fop.pdf.PDFPage;
import org.apache.fop.pdf.PDFResources;
+import org.apache.fop.pdf.PDFStream;
import org.apache.fop.render.pdf.pdfbox.FOPPDFMultiByteFont;
import org.apache.fop.render.pdf.pdfbox.FOPPDFSingleByteFont;
import org.apache.fop.render.pdf.pdfbox.ImageConverterPDF2G2D;
@@ -511,4 +512,23 @@ public class PDFBoxAdapterTestCase {
res.output(bos);
Assert.assertTrue(bos.toString("UTF-8").contains("/ExtGState << /GS1"));
}
+
+ @Test
+ public void testPDFCache() throws IOException {
+ PDFDocument pdfdoc = new PDFDocument("");
+ PDFPage pdfpage = new PDFPage(new PDFResources(pdfdoc), 0, r, r, r, r);
+ pdfdoc.assignObjectNumber(pdfpage);
+ pdfpage.setDocument(pdfdoc);
+ Map<Object, Object> pdfCache = new HashMap<Object, Object>();
+ PDFBoxAdapter adapter = new PDFBoxAdapter(
+ pdfpage, new HashMap<Object, Object>(), 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());
+ doc.close();
+
+ Object item = pdfCache.values().iterator().next();
+ Assert.assertEquals(item.getClass(), PDFStream.class);
+ Assert.assertEquals(pdfCache.size(), 11);
+ }
}
---------------------------------------------------------------------
To unsubscribe, e-mail: fop-commits-unsubscribe@xmlgraphics.apache.org
For additional commands, e-mail: fop-commits-help@xmlgraphics.apache.org