]> source.dussan.org Git - poi.git/commitdiff
#58193 - Use input stream rather than byte array for checksum etc.
authorAndreas Beeker <kiwiwings@apache.org>
Sat, 1 Aug 2015 20:09:37 +0000 (20:09 +0000)
committerAndreas Beeker <kiwiwings@apache.org>
Sat, 1 Aug 2015 20:09:37 +0000 (20:09 +0000)
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
src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFPictureData.java
src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFPictureShape.java

index b5f22a1a1a2b558b2319a1a85a465132cddd073b..0fa415de6841a308943cb92072dd8e93c20076be 100644 (file)
@@ -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.
index 98c3b7c9fef4c4b0a0b3810580a13f8259165f29..8e20be90b323fa1bec35f1fa9e685878a5476299 100644 (file)
@@ -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;
@@ -140,22 +141,26 @@ public final class XSLFPictureData extends POIXMLDocumentPart implements Picture
         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.
-     * <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);
     }
     
     
index 0ec83497a47b0f347ce54c96d47ff8cc6c4d883b..73ec45b9a8ab3008604692d1909a09130c3abe8b 100644 (file)
@@ -22,7 +22,6 @@ package org.apache.poi.xslf.usermodel;
 import java.awt.Insets;\r
 import java.awt.geom.Rectangle2D;\r
 import java.awt.image.BufferedImage;\r
-import java.io.ByteArrayInputStream;\r
 import java.net.URI;\r
 \r
 import javax.imageio.ImageIO;\r
@@ -91,10 +90,8 @@ public class XSLFPictureShape extends XSLFSimpleShape implements PictureShape {
      * for other types sets the default size of 200x200 pixels.\r
      */\r
     public void resize() {\r
-        XSLFPictureData pict = getPictureData();\r
-\r
         try {\r
-            BufferedImage img = ImageIO.read(new ByteArrayInputStream(pict.getData()));\r
+            BufferedImage img = ImageIO.read(getPictureData().getInputStream());\r
             setAnchor(new Rectangle2D.Double(0, 0, img.getWidth(), img.getHeight()));\r
         }\r
         catch (Exception e) {\r