diff options
3 files changed, 45 insertions, 15 deletions
diff --git a/src/java/org/apache/poi/util/IOUtils.java b/src/java/org/apache/poi/util/IOUtils.java index b5f22a1a1a..0fa415de68 100644 --- a/src/java/org/apache/poi/util/IOUtils.java +++ b/src/java/org/apache/poi/util/IOUtils.java @@ -166,6 +166,9 @@ 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); @@ -173,6 +176,26 @@ public final class IOUtils { } /** + * 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 98c3b7c9fe..8e20be90b3 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 } /** + * 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. - * <p> - * 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: - * <br/> - * <code> - * InputStream is = getPackagePart().getInputStream(); - * </code> - * </p> * + * 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 0ec83497a4..73ec45b9a8 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) {
|