aboutsummaryrefslogtreecommitdiffstats
path: root/src/ooxml
diff options
context:
space:
mode:
Diffstat (limited to 'src/ooxml')
-rw-r--r--src/ooxml/java/org/apache/poi/xslf/usermodel/XMLSlideShow.java26
-rw-r--r--src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFPictureData.java70
-rw-r--r--src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFPictureShape.java25
-rw-r--r--src/ooxml/testcases/org/apache/poi/xslf/TestXSLFBugs.java50
-rw-r--r--src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFPictureShape.java49
5 files changed, 154 insertions, 66 deletions
diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XMLSlideShow.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XMLSlideShow.java
index 2cf4bda982..a327630ba8 100644
--- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XMLSlideShow.java
+++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XMLSlideShow.java
@@ -21,6 +21,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
@@ -42,6 +43,8 @@ import org.apache.poi.sl.usermodel.SlideShow;
import org.apache.poi.util.Beta;
import org.apache.poi.util.IOUtils;
import org.apache.poi.util.Internal;
+import org.apache.poi.util.LittleEndian;
+import org.apache.poi.util.LittleEndianConsts;
import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger;
import org.apache.poi.util.PackageHelper;
@@ -106,12 +109,18 @@ implements SlideShow<XSLFShape,XSLFTextParagraph> {
static final OPCPackage empty() {
InputStream is = XMLSlideShow.class.getResourceAsStream("empty.pptx");
if (is == null) {
- throw new RuntimeException("Missing resource 'empty.pptx'");
+ throw new POIXMLException("Missing resource 'empty.pptx'");
}
try {
return OPCPackage.open(is);
} catch (Exception e){
throw new POIXMLException(e);
+ } finally {
+ try {
+ is.close();
+ } catch (Exception e) {
+ throw new POIXMLException(e);
+ }
}
}
@@ -189,12 +198,8 @@ implements SlideShow<XSLFShape,XSLFTextParagraph> {
);
}
- /**
- * Returns all Pictures, which are referenced from the document itself.
- * @return a {@link List} of {@link PackagePart}.
- * The returned {@link List} is unmodifiable.
- */
- public List<XSLFPictureData> getAllPictures() {
+ @Override
+ public List<XSLFPictureData> getPictureData() {
if(_pictures == null){
List<PackagePart> mediaParts = getPackage().getPartsByName(Pattern.compile("/ppt/media/.*?"));
_pictures = new ArrayList<XSLFPictureData>(mediaParts.size());
@@ -472,8 +477,11 @@ implements SlideShow<XSLFShape,XSLFTextParagraph> {
*/
XSLFPictureData findPictureData(byte[] pictureData){
long checksum = IOUtils.calculateChecksum(pictureData);
- for(XSLFPictureData pic : getAllPictures()){
- if(pic.getChecksum() == checksum) {
+ byte cs[] = new byte[LittleEndianConsts.LONG_SIZE];
+ LittleEndian.putLong(cs,0,checksum);
+
+ for(XSLFPictureData pic : getPictureData()){
+ if(Arrays.equals(pic.getChecksum(), cs)) {
return pic;
}
}
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 e6fc0fd4ef..b2d407d231 100644
--- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFPictureData.java
+++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFPictureData.java
@@ -19,24 +19,41 @@
package org.apache.poi.xslf.usermodel;
+import java.awt.Dimension;
+import java.awt.image.BufferedImage;
+import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
+import javax.imageio.ImageIO;
+
import org.apache.poi.POIXMLDocumentPart;
import org.apache.poi.POIXMLException;
+import org.apache.poi.hslf.blip.EMF;
+import org.apache.poi.hslf.blip.PICT;
+import org.apache.poi.hslf.blip.WMF;
import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.openxml4j.opc.PackageRelationship;
import org.apache.poi.sl.usermodel.PictureData;
import org.apache.poi.util.Beta;
import org.apache.poi.util.IOUtils;
+import org.apache.poi.util.LittleEndian;
+import org.apache.poi.util.LittleEndianConsts;
+import org.apache.poi.util.POILogFactory;
+import org.apache.poi.util.POILogger;
/**
* Instantiates sub-classes of POIXMLDocumentPart depending on their relationship type
*/
@Beta
public final class XSLFPictureData extends POIXMLDocumentPart implements PictureData {
+ private static final POILogger logger = POILogFactory.getLogger(XSLFPictureData.class);
+
private Long checksum = null;
+
+ // original image dimensions (for formats supported by BufferedImage)
+ private Dimension _origSize = null;
private int index = -1;
/**
@@ -103,15 +120,52 @@ public final class XSLFPictureData extends POIXMLDocumentPart implements Picture
return getPackagePart().getPartName().getExtension();
}
- long getChecksum(){
- if(checksum == null){
- try {
- checksum = IOUtils.calculateChecksum(getInputStream());
- } catch (IOException e) {
- throw new POIXMLException("Unable to calulate checksum", e);
+ @Override
+ public byte[] getChecksum() {
+ cacheProperties();
+ byte cs[] = new byte[LittleEndianConsts.LONG_SIZE];
+ LittleEndian.putLong(cs,0,checksum);
+ return cs;
+ }
+
+ @Override
+ public Dimension getImageDimension() {
+ cacheProperties();
+ return _origSize;
+ }
+
+ /**
+ * Determine and cache image properties
+ */
+ protected void cacheProperties() {
+ if (_origSize == null || checksum == null) {
+ byte data[] = getData();
+ checksum = IOUtils.calculateChecksum(data);
+
+ switch (getType()) {
+ case EMF:
+ _origSize = new EMF.NativeHeader(data, 0).getSize();
+ break;
+ case WMF:
+ // wmf files in pptx usually have their placeable header
+ // stripped away, so this returns only the dummy size
+ _origSize = new WMF.NativeHeader(data, 0).getSize();
+ break;
+ case PICT:
+ _origSize = new PICT.NativeHeader(data, 0).getSize();
+ break;
+ default:
+ try {
+ BufferedImage img = ImageIO.read(new ByteArrayInputStream(data));
+ _origSize = (img == null) ? new Dimension() : new Dimension(img.getWidth(), img.getHeight());
+ } catch (IOException e) {
+ logger.log(POILogger.WARN, "Can't determine image dimensions", e);
+ // failed to get information, set dummy size
+ _origSize = new Dimension(200,200);
+ }
+ break;
}
}
- return checksum;
}
/**
@@ -134,6 +188,8 @@ public final class XSLFPictureData extends POIXMLDocumentPart implements Picture
os.close();
// recalculate now since we already have the data bytes available anyhow
checksum = IOUtils.calculateChecksum(data);
+
+ _origSize = null; // need to recalculate image size
}
@Override
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 0dc14844ea..df352b57d0 100644
--- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFPictureShape.java
+++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFPictureShape.java
@@ -19,12 +19,10 @@
package org.apache.poi.xslf.usermodel;
+import java.awt.Dimension;
import java.awt.Insets;
-import java.awt.geom.Rectangle2D;
-import java.awt.image.BufferedImage;
+import java.awt.Rectangle;
import java.net.URI;
-
-import javax.imageio.ImageIO;
import javax.xml.namespace.QName;
import org.apache.poi.POIXMLException;
@@ -87,20 +85,23 @@ public class XSLFPictureShape extends XSLFSimpleShape
/**
* Resize this picture to the default size.
+ *
* For PNG and JPEG resizes the image to 100%,
- * for other types sets the default size of 200x200 pixels.
+ * for other types sets the default size to 200x200 pixels.
*/
public void resize() {
- try {
- BufferedImage img = ImageIO.read(getPictureData().getInputStream());
- setAnchor(new Rectangle2D.Double(0, 0, img.getWidth(), img.getHeight()));
+ Dimension dim = getPictureData().getImageDimension();
+ if (dim.width > 0 && dim.height > 0)
+ {
+ setAnchor(new Rectangle(0, 0, dim.width, dim.height));
}
- catch (Exception e) {
- //default size is 200x200
- setAnchor(new java.awt.Rectangle(50, 50, 200, 200));
+ else
+ {
+ // unsupported/unknown formats
+ setAnchor(new Rectangle(50, 50, 200, 200));
}
}
-
+
/**
* Is this an internal picture (image data included within
* the PowerPoint file), or an external linked picture
diff --git a/src/ooxml/testcases/org/apache/poi/xslf/TestXSLFBugs.java b/src/ooxml/testcases/org/apache/poi/xslf/TestXSLFBugs.java
index cd78f6565e..0f1d14f4cb 100644
--- a/src/ooxml/testcases/org/apache/poi/xslf/TestXSLFBugs.java
+++ b/src/ooxml/testcases/org/apache/poi/xslf/TestXSLFBugs.java
@@ -58,14 +58,14 @@ public class TestXSLFBugs {
@Test
@SuppressWarnings("deprecation")
public void bug51187() throws Exception {
- XMLSlideShow ss = XSLFTestDataSamples.openSampleDocument("51187.pptx");
+ XMLSlideShow ss1 = XSLFTestDataSamples.openSampleDocument("51187.pptx");
- assertEquals(1, ss.getSlides().size());
+ assertEquals(1, ss1.getSlides().size());
// Check the relations on it
// Note - rId3 is a self reference
- PackagePart slidePart = ss._getXSLFSlideShow().getSlidePart(
- ss._getXSLFSlideShow().getSlideReferences().getSldIdArray(0)
+ PackagePart slidePart = ss1._getXSLFSlideShow().getSlidePart(
+ ss1._getXSLFSlideShow().getSlideReferences().getSldIdArray(0)
);
assertEquals("/ppt/slides/slide1.xml", slidePart.getPartName().toString());
assertEquals("/ppt/slideLayouts/slideLayout12.xml", slidePart.getRelationship("rId1").getTargetURI().toString());
@@ -74,11 +74,12 @@ public class TestXSLFBugs {
assertEquals("/ppt/media/image1.png", slidePart.getRelationship("rId4").getTargetURI().toString());
// Save and re-load
- ss = XSLFTestDataSamples.writeOutAndReadBack(ss);
- assertEquals(1, ss.getSlides().size());
+ XMLSlideShow ss2 = XSLFTestDataSamples.writeOutAndReadBack(ss1);
+ ss1.close();
+ assertEquals(1, ss2.getSlides().size());
- slidePart = ss._getXSLFSlideShow().getSlidePart(
- ss._getXSLFSlideShow().getSlideReferences().getSldIdArray(0)
+ slidePart = ss2._getXSLFSlideShow().getSlidePart(
+ ss2._getXSLFSlideShow().getSlideReferences().getSldIdArray(0)
);
assertEquals("/ppt/slides/slide1.xml", slidePart.getPartName().toString());
assertEquals("/ppt/slideLayouts/slideLayout12.xml", slidePart.getRelationship("rId1").getTargetURI().toString());
@@ -86,13 +87,15 @@ public class TestXSLFBugs {
// TODO Fix this
assertEquals("/ppt/slides/slide1.xml", slidePart.getRelationship("rId3").getTargetURI().toString());
assertEquals("/ppt/media/image1.png", slidePart.getRelationship("rId4").getTargetURI().toString());
+
+ ss2.close();
}
/**
* Slide relations with anchors in them
*/
@Test
- public void tika705() {
+ public void tika705() throws Exception {
XMLSlideShow ss = XSLFTestDataSamples.openSampleDocument("with_japanese.pptx");
// Should have one slide
@@ -132,6 +135,7 @@ public class TestXSLFBugs {
}
}
}
+ ss.close();
}
/**
@@ -161,6 +165,8 @@ public class TestXSLFBugs {
slide = ss.getSlides().get(3);
assertContains("POI can read this", getSlideText(slide));
+
+ ss.close();
}
/**
@@ -197,6 +203,7 @@ public class TestXSLFBugs {
assertEquals(2, internalPictures);
assertEquals(1, externalPictures);
+ ppt.close();
}
@Test
@@ -225,6 +232,7 @@ public class TestXSLFBugs {
slide.draw(graphics);
ImageIO.write(imgActual, "PNG", new File("bug54542.png"));
+ ss.close();
}
protected String getSlideText(XSLFSlide slide) {
@@ -262,6 +270,7 @@ public class TestXSLFBugs {
ss.setSlideOrder(slide, 0);
ss.setSlideOrder(slide, 2);
validateSlides(ss, true, "Slide1","Slide2","New slide");
+ ss.close();
}
/**
@@ -277,7 +286,7 @@ public class TestXSLFBugs {
// Slide starts with just layout relation
XSLFSlide slide = ss.getSlides().get(0);
- assertEquals(0, ss.getAllPictures().size());
+ assertEquals(0, ss.getPictureData().size());
assertEquals(1, slide.getShapes().size());
assertEquals(1, slide.getRelations().size());
@@ -295,7 +304,7 @@ public class TestXSLFBugs {
for (int i=0; i<10; i++) {
XSLFPictureData data = ss.addPicture(pics[i], PictureType.JPEG);
assertEquals(i, data.getIndex());
- assertEquals(i+1, ss.getAllPictures().size());
+ assertEquals(i+1, ss.getPictureData().size());
XSLFPictureShape shape = slide.createPicture(data);
assertNotNull(shape.getPictureData());
@@ -313,7 +322,7 @@ public class TestXSLFBugs {
for (int i=10; i<15; i++) {
XSLFPictureData data = ss.addPicture(pics[i], PictureType.JPEG);
assertEquals(i, data.getIndex());
- assertEquals(i+1, ss.getAllPictures().size());
+ assertEquals(i+1, ss.getPictureData().size());
XSLFPictureShape shape = slide.createPicture(data);
assertNotNull(shape.getPictureData());
@@ -330,7 +339,7 @@ public class TestXSLFBugs {
// Add a duplicate, check the right one is picked
XSLFPictureData data = ss.addPicture(pics[3], PictureType.JPEG);
assertEquals(3, data.getIndex());
- assertEquals(15, ss.getAllPictures().size());
+ assertEquals(15, ss.getPictureData().size());
XSLFPictureShape shape = slide.createPicture(data);
assertNotNull(shape.getPictureData());
@@ -357,7 +366,7 @@ public class TestXSLFBugs {
// Add another duplicate
data = ss2.addPicture(pics[5], PictureType.JPEG);
assertEquals(5, data.getIndex());
- assertEquals(15, ss2.getAllPictures().size());
+ assertEquals(15, ss2.getPictureData().size());
shape = slide.createPicture(data);
assertNotNull(shape.getPictureData());
@@ -368,11 +377,17 @@ public class TestXSLFBugs {
ss.close();
}
- private void validateSlides(XMLSlideShow ss, boolean saveAndReload, String... slideTexts) {
+ private void validateSlides(XMLSlideShow ss, boolean saveAndReload, String... slideTexts) throws IOException {
if (saveAndReload) {
- ss = XSLFTestDataSamples.writeOutAndReadBack(ss);
+ XMLSlideShow ss2 = XSLFTestDataSamples.writeOutAndReadBack(ss);
+ validateSlides(ss, slideTexts);
+ ss2.close();
+ } else {
+ validateSlides(ss, slideTexts);
}
-
+ }
+
+ private void validateSlides(XMLSlideShow ss, String... slideTexts) throws IOException {
assertEquals(slideTexts.length, ss.getSlides().size());
for (int i = 0; i < slideTexts.length; i++) {
@@ -380,6 +395,7 @@ public class TestXSLFBugs {
assertContains(getSlideText(slide), slideTexts[i]);
}
}
+
private void assertRelationEquals(XSLFRelation expected, POIXMLDocumentPart relation) {
assertEquals(expected.getContentType(), relation.getPackagePart().getContentType());
assertEquals(expected.getFileName(expected.getFileNameIndex(relation)), relation.getPackagePart().getPartName().getName());
diff --git a/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFPictureShape.java b/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFPictureShape.java
index 12dde34afe..b5acb85291 100644
--- a/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFPictureShape.java
+++ b/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFPictureShape.java
@@ -36,44 +36,46 @@ import org.openxmlformats.schemas.presentationml.x2006.main.CTPicture;
public class TestXSLFPictureShape {
@Test
- public void testCreate() {
- XMLSlideShow ppt = new XMLSlideShow();
- assertEquals(0, ppt.getAllPictures().size());
+ public void testCreate() throws Exception {
+ XMLSlideShow ppt1 = new XMLSlideShow();
+ assertEquals(0, ppt1.getPictureData().size());
byte[] data1 = new byte[100];
for(int i = 0;i < 100;i++) { data1[i] = (byte)i; }
- XSLFPictureData pdata1 = ppt.addPicture(data1, PictureType.JPEG);
+ XSLFPictureData pdata1 = ppt1.addPicture(data1, PictureType.JPEG);
assertEquals(0, pdata1.getIndex());
- assertEquals(1, ppt.getAllPictures().size());
+ assertEquals(1, ppt1.getPictureData().size());
- XSLFSlide slide = ppt.createSlide();
+ XSLFSlide slide = ppt1.createSlide();
XSLFPictureShape shape1 = slide.createPicture(pdata1);
assertNotNull(shape1.getPictureData());
assertArrayEquals(data1, shape1.getPictureData().getData());
byte[] data2 = new byte[200];
for(int i = 0;i < 200;i++) { data2[i] = (byte)i; }
- XSLFPictureData pdata2 = ppt.addPicture(data2, PictureType.PNG);
+ XSLFPictureData pdata2 = ppt1.addPicture(data2, PictureType.PNG);
XSLFPictureShape shape2 = slide.createPicture(pdata2);
assertNotNull(shape2.getPictureData());
assertEquals(1, pdata2.getIndex());
- assertEquals(2, ppt.getAllPictures().size());
+ assertEquals(2, ppt1.getPictureData().size());
assertArrayEquals(data2, shape2.getPictureData().getData());
- ppt = XSLFTestDataSamples.writeOutAndReadBack(ppt);
- List<XSLFPictureData> pics = ppt.getAllPictures();
+ XMLSlideShow ppt2 = XSLFTestDataSamples.writeOutAndReadBack(ppt1);
+ ppt1.close();
+ List<XSLFPictureData> pics = ppt2.getPictureData();
assertEquals(2, pics.size());
assertArrayEquals(data1, pics.get(0).getData());
assertArrayEquals(data2, pics.get(1).getData());
- List<XSLFShape> shapes = ppt.getSlides().get(0).getShapes();
+ List<XSLFShape> shapes = ppt2.getSlides().get(0).getShapes();
assertArrayEquals(data1, ((XSLFPictureShape) shapes.get(0)).getPictureData().getData());
assertArrayEquals(data2, ((XSLFPictureShape) shapes.get(1)).getPictureData().getData());
+ ppt2.close();
}
@Test
- public void testCreateMultiplePictures() {
- XMLSlideShow ppt = new XMLSlideShow();
- XSLFSlide slide1 = ppt.createSlide();
+ public void testCreateMultiplePictures() throws Exception {
+ XMLSlideShow ppt1 = new XMLSlideShow();
+ XSLFSlide slide1 = ppt1.createSlide();
XSLFGroupShape group1 = slide1.createGroup();
@@ -81,7 +83,7 @@ public class TestXSLFPictureShape {
// first add 20 images to the slide
for (int i = 0; i < 20; i++, pictureIndex++) {
byte[] data = new byte[]{(byte)pictureIndex};
- XSLFPictureData elementData = ppt.addPicture(data, PictureType.PNG);
+ XSLFPictureData elementData = ppt1.addPicture(data, PictureType.PNG);
assertEquals(pictureIndex, elementData.getIndex()); // added images have indexes 0,1,2....19
XSLFPictureShape picture = slide1.createPicture(elementData);
// POI saves images as image1.png, image2.png, etc.
@@ -93,7 +95,7 @@ public class TestXSLFPictureShape {
// and then add next 20 images to a group
for (int i = 0; i < 20; i++, pictureIndex++) {
byte[] data = new byte[]{(byte)pictureIndex};
- XSLFPictureData elementData = ppt.addPicture(data, PictureType.PNG);
+ XSLFPictureData elementData = ppt1.addPicture(data, PictureType.PNG);
XSLFPictureShape picture = group1.createPicture(elementData);
// POI saves images as image1.png, image2.png, etc.
assertEquals(pictureIndex, elementData.getIndex()); // added images have indexes 0,1,2....19
@@ -104,10 +106,11 @@ public class TestXSLFPictureShape {
// serialize, read back and check that all images are there
- ppt = XSLFTestDataSamples.writeOutAndReadBack(ppt);
+ XMLSlideShow ppt2 = XSLFTestDataSamples.writeOutAndReadBack(ppt1);
+ ppt1.close();
// pictures keyed by file name
Map<String, XSLFPictureData> pics = new HashMap<String, XSLFPictureData>();
- for(XSLFPictureData p : ppt.getAllPictures()){
+ for(XSLFPictureData p : ppt2.getPictureData()){
pics.put(p.getFileName(), p);
}
assertEquals(40, pics.size());
@@ -119,10 +122,11 @@ public class TestXSLFPictureShape {
assertEquals(fileName, data.getFileName());
assertArrayEquals(data1, data.getData());
}
+ ppt2.close();
}
@Test
- public void testImageCaching() {
+ public void testImageCaching() throws Exception {
XMLSlideShow ppt = new XMLSlideShow();
byte[] img1 = new byte[]{1,2,3};
byte[] img2 = new byte[]{3,4,5};
@@ -139,10 +143,11 @@ public class TestXSLFPictureShape {
XSLFSlide slide2 = ppt.createSlide();
assertNotNull(slide2);
+ ppt.close();
}
@Test
- public void testMerge() {
+ public void testMerge() throws Exception {
XMLSlideShow ppt1 = new XMLSlideShow();
byte[] data1 = new byte[100];
XSLFPictureData pdata1 = ppt1.addPicture(data1, PictureType.JPEG);
@@ -151,7 +156,7 @@ public class TestXSLFPictureShape {
XSLFPictureShape shape1 = slide1.createPicture(pdata1);
CTPicture ctPic1 = (CTPicture)shape1.getXmlObject();
ctPic1.getNvPicPr().getNvPr().addNewCustDataLst().addNewTags().setId("rId99");
-
+
XMLSlideShow ppt2 = new XMLSlideShow();
XSLFSlide slide2 = ppt2.createSlide().importContent(slide1);
@@ -162,5 +167,7 @@ public class TestXSLFPictureShape {
CTPicture ctPic2 = (CTPicture)shape2.getXmlObject();
assertFalse(ctPic2.getNvPicPr().getNvPr().isSetCustDataLst());
+ ppt1.close();
+ ppt2.close();
}
} \ No newline at end of file