#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
This commit is contained in:
Andreas Beeker 2015-08-01 20:09:37 +00:00
parent 7668a61058
commit 98ed7bb5fb
3 changed files with 46 additions and 16 deletions

View File

@ -166,12 +166,35 @@ public final class IOUtils {
} }
} }
/**
* Calculate checksum on input data
*/
public static long calculateChecksum(byte[] data) { public static long calculateChecksum(byte[] data) {
Checksum sum = new CRC32(); Checksum sum = new CRC32();
sum.update(data, 0, data.length); sum.update(data, 0, data.length);
return sum.getValue(); 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 * Quietly (no exceptions) close Closable resource. In case of error it will
* be printed to {@link IOUtils} class logger. * be printed to {@link IOUtils} class logger.

View File

@ -20,6 +20,7 @@
package org.apache.poi.xslf.usermodel; package org.apache.poi.xslf.usermodel;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import org.apache.poi.POIXMLDocumentPart; import org.apache.poi.POIXMLDocumentPart;
@ -140,22 +141,26 @@ public final class XSLFPictureData extends POIXMLDocumentPart implements Picture
super(part, rel); super(part, rel);
} }
/**
* 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. * 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 with the {@link #getInputStream()} method
* You can grab the picture data directly from the underlying package part as follows:
* <br/>
* <code>
* InputStream is = getPackagePart().getInputStream();
* </code>
* </p>
* *
* @return the Picture data. * @return the Picture data.
*/ */
public byte[] getData() { public byte[] getData() {
try { try {
return IOUtils.toByteArray(getPackagePart().getInputStream()); return IOUtils.toByteArray(getInputStream());
} catch (IOException e) { } catch (IOException e) {
throw new POIXMLException(e); throw new POIXMLException(e);
} }
@ -203,8 +208,11 @@ public final class XSLFPictureData extends POIXMLDocumentPart implements Picture
long getChecksum(){ long getChecksum(){
if(checksum == null){ if(checksum == null){
byte[] pictureData = getData(); try {
checksum = IOUtils.calculateChecksum(pictureData); checksum = IOUtils.calculateChecksum(getInputStream());
} catch (IOException e) {
throw new POIXMLException("Unable to calulate checksum", e);
}
} }
return checksum; return checksum;
} }
@ -227,6 +235,8 @@ public final class XSLFPictureData extends POIXMLDocumentPart implements Picture
OutputStream os = getPackagePart().getOutputStream(); OutputStream os = getPackagePart().getOutputStream();
os.write(data); os.write(data);
os.close(); os.close();
// recalculate now since we already have the data bytes available anyhow
checksum = IOUtils.calculateChecksum(data);
} }

View File

@ -22,7 +22,6 @@ package org.apache.poi.xslf.usermodel;
import java.awt.Insets; import java.awt.Insets;
import java.awt.geom.Rectangle2D; import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.net.URI; import java.net.URI;
import javax.imageio.ImageIO; 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. * for other types sets the default size of 200x200 pixels.
*/ */
public void resize() { public void resize() {
XSLFPictureData pict = getPictureData();
try { 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())); setAnchor(new Rectangle2D.Double(0, 0, img.getWidth(), img.getHeight()));
} }
catch (Exception e) { catch (Exception e) {