From 98ed7bb5fb0804d2db9f3075b15b841fb6aa4439 Mon Sep 17 00:00:00 2001 From: Andreas Beeker Date: Sat, 1 Aug 2015 20:09:37 +0000 Subject: [PATCH] #58193 - Use input stream rather than byte array for checksum etc. git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1693754 13f79535-47bb-0310-9956-ffa450edef68 --- src/java/org/apache/poi/util/IOUtils.java | 23 +++++++++++++ .../poi/xslf/usermodel/XSLFPictureData.java | 34 ++++++++++++------- .../poi/xslf/usermodel/XSLFPictureShape.java | 5 +-- 3 files changed, 46 insertions(+), 16 deletions(-) diff --git a/src/java/org/apache/poi/util/IOUtils.java b/src/java/org/apache/poi/util/IOUtils.java index b5f22a1a1..0fa415de6 100644 --- a/src/java/org/apache/poi/util/IOUtils.java +++ b/src/java/org/apache/poi/util/IOUtils.java @@ -166,12 +166,35 @@ public final class IOUtils { } } + /** + * Calculate checksum on input data + */ public static long calculateChecksum(byte[] data) { Checksum sum = new CRC32(); sum.update(data, 0, data.length); return sum.getValue(); } + /** + * Calculate checksum on all the data read from input stream. + * + * This should be more efficient than the equivalent code + * {@code IOUtils.calculateChecksum(IOUtils.toByteArray(stream))} + */ + public static long calculateChecksum(InputStream stream) throws IOException { + Checksum sum = new CRC32(); + + byte[] buf = new byte[4096]; + int count; + while ((count = stream.read(buf)) != -1) { + if (count > 0) { + sum.update(buf, 0, count); + } + } + return sum.getValue(); + } + + /** * Quietly (no exceptions) close Closable resource. In case of error it will * be printed to {@link IOUtils} class logger. diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFPictureData.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFPictureData.java index 98c3b7c9f..8e20be90b 100644 --- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFPictureData.java +++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFPictureData.java @@ -20,6 +20,7 @@ package org.apache.poi.xslf.usermodel; import java.io.IOException; +import java.io.InputStream; import java.io.OutputStream; import org.apache.poi.POIXMLDocumentPart; @@ -141,21 +142,25 @@ public final class XSLFPictureData extends POIXMLDocumentPart implements Picture } /** - * Gets the picture data as a byte array. - *

- * Note, that this call might be expensive since all the picture data is copied into a temporary byte array. - * You can grab the picture data directly from the underlying package part as follows: - *
- * - * InputStream is = getPackagePart().getInputStream(); - * - *

+ * An InputStream to read the picture data directly + * from the underlying package part * + * @return InputStream + */ + public InputStream getInputStream() throws IOException { + return getPackagePart().getInputStream(); + } + + /** + * Gets the picture data as a byte array. + * + * You can grab the picture data directly from the underlying package part with the {@link #getInputStream()} method + * * @return the Picture data. */ public byte[] getData() { try { - return IOUtils.toByteArray(getPackagePart().getInputStream()); + return IOUtils.toByteArray(getInputStream()); } catch (IOException e) { throw new POIXMLException(e); } @@ -203,8 +208,11 @@ public final class XSLFPictureData extends POIXMLDocumentPart implements Picture long getChecksum(){ if(checksum == null){ - byte[] pictureData = getData(); - checksum = IOUtils.calculateChecksum(pictureData); + try { + checksum = IOUtils.calculateChecksum(getInputStream()); + } catch (IOException e) { + throw new POIXMLException("Unable to calulate checksum", e); + } } return checksum; } @@ -227,6 +235,8 @@ public final class XSLFPictureData extends POIXMLDocumentPart implements Picture OutputStream os = getPackagePart().getOutputStream(); os.write(data); os.close(); + // recalculate now since we already have the data bytes available anyhow + checksum = IOUtils.calculateChecksum(data); } diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFPictureShape.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFPictureShape.java index 0ec83497a..73ec45b9a 100644 --- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFPictureShape.java +++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFPictureShape.java @@ -22,7 +22,6 @@ package org.apache.poi.xslf.usermodel; import java.awt.Insets; import java.awt.geom.Rectangle2D; import java.awt.image.BufferedImage; -import java.io.ByteArrayInputStream; import java.net.URI; import javax.imageio.ImageIO; @@ -91,10 +90,8 @@ public class XSLFPictureShape extends XSLFSimpleShape implements PictureShape { * for other types sets the default size of 200x200 pixels. */ public void resize() { - XSLFPictureData pict = getPictureData(); - try { - BufferedImage img = ImageIO.read(new ByteArrayInputStream(pict.getData())); + BufferedImage img = ImageIO.read(getPictureData().getInputStream()); setAnchor(new Rectangle2D.Double(0, 0, img.getWidth(), img.getHeight())); } catch (Exception e) {