diff --git a/src/documentation/content/xdocs/changes.xml b/src/documentation/content/xdocs/changes.xml
index f2aaf8db12..120656ca95 100644
--- a/src/documentation/content/xdocs/changes.xml
+++ b/src/documentation/content/xdocs/changes.xml
@@ -37,7 +37,7 @@
- remove me
+ 46627 - Fixed offset of added images if Pictures stream contains pictures with zero length
46536 - When shifting rows, update formulas on that sheet to point to the new location of those rows
diff --git a/src/documentation/content/xdocs/status.xml b/src/documentation/content/xdocs/status.xml
index bee0982ecc..f8b6fb674d 100644
--- a/src/documentation/content/xdocs/status.xml
+++ b/src/documentation/content/xdocs/status.xml
@@ -34,7 +34,7 @@
- remove me
+ 46627 - Fixed offset of added images if Pictures stream contains pictures with zero length
46536 - When shifting rows, update formulas on that sheet to point to the new location of those rows
diff --git a/src/scratchpad/src/org/apache/poi/hslf/HSLFSlideShow.java b/src/scratchpad/src/org/apache/poi/hslf/HSLFSlideShow.java
index 8273d87cc5..c0a92a3188 100644
--- a/src/scratchpad/src/org/apache/poi/hslf/HSLFSlideShow.java
+++ b/src/scratchpad/src/org/apache/poi/hslf/HSLFSlideShow.java
@@ -66,7 +66,7 @@ public final class HSLFSlideShow extends POIDocument {
private Record[] _records;
// Raw Pictures contained in the pictures stream
- private PictureData[] _pictures;
+ private List _pictures;
// Embedded objects stored in storage records in the document stream, lazily populated.
private ObjectData[] _objects;
@@ -291,6 +291,8 @@ public final class HSLFSlideShow extends POIDocument {
* Find and read in pictures contained in this presentation
*/
private void readPictures() throws IOException {
+ _pictures = new ArrayList();
+
byte[] pictstream;
try {
@@ -304,9 +306,7 @@ public final class HSLFSlideShow extends POIDocument {
return;
}
- List p = new ArrayList();
int pos = 0;
-
// An empty picture record (length 0) will take up 8 bytes
while (pos <= (pictstream.length-8)) {
int offset = pos;
@@ -325,7 +325,7 @@ public final class HSLFSlideShow extends POIDocument {
// (0 is allowed, but odd, since we do wind on by the header each
// time, so we won't get stuck)
if(imgsize < 0) {
- throw new CorruptPowerPointFileException("The file contains a picture, at position " + p.size() + ", which has a negatively sized data length, so we can't trust any of the picture data");
+ throw new CorruptPowerPointFileException("The file contains a picture, at position " + _pictures.size() + ", which has a negatively sized data length, so we can't trust any of the picture data");
}
// If they type (including the bonus 0xF018) is 0, skip it
@@ -343,7 +343,7 @@ public final class HSLFSlideShow extends POIDocument {
pict.setRawData(imgdata);
pict.setOffset(offset);
- p.add(pict);
+ _pictures.add(pict);
} catch(IllegalArgumentException e) {
logger.log(POILogger.ERROR, "Problem reading picture: " + e + "\nYou document will probably become corrupted if you save it!");
}
@@ -351,8 +351,6 @@ public final class HSLFSlideShow extends POIDocument {
pos += imgsize;
}
-
- _pictures = (PictureData[])p.toArray(new PictureData[p.size()]);
}
@@ -453,10 +451,10 @@ public final class HSLFSlideShow extends POIDocument {
// Write any pictures, into another stream
- if (_pictures != null) {
+ if (_pictures.size() > 0) {
ByteArrayOutputStream pict = new ByteArrayOutputStream();
- for (int i = 0; i < _pictures.length; i++ ) {
- _pictures[i].write(pict);
+ for (PictureData p : _pictures) {
+ p.write(pict);
}
outFS.createDocument(
new ByteArrayInputStream(pict.toByteArray()), "Pictures"
@@ -502,21 +500,21 @@ public final class HSLFSlideShow extends POIDocument {
}
/**
- * Add a new picture to this presentation.
+ * Add a new picture to this presentation.
+ *
+ * @return offset of this picture in the Pictures stream
*/
- public void addPicture(PictureData img) {
- // Copy over the existing pictures, into an array one bigger
- PictureData[] lst;
- if(_pictures == null) {
- lst = new PictureData[1];
- } else {
- lst = new PictureData[(_pictures.length+1)];
- System.arraycopy(_pictures,0,lst,0,_pictures.length);
- }
- // Add in the new image
- lst[lst.length - 1] = img;
- _pictures = lst;
- }
+ public int addPicture(PictureData img) {
+ int offset = 0;
+
+ if(_pictures.size() > 0){
+ PictureData prev = _pictures.get(_pictures.size() - 1);
+ offset = prev.getOffset() + prev.getRawData().length + 8;
+ }
+ img.setOffset(offset);
+ _pictures.add(img);
+ return offset;
+ }
/* ******************* fetching methods follow ********************* */
@@ -544,7 +542,7 @@ public final class HSLFSlideShow extends POIDocument {
* presentation doesn't contain pictures.
*/
public PictureData[] getPictures() {
- return _pictures;
+ return _pictures.toArray(new PictureData[_pictures.size()]);
}
/**
diff --git a/src/scratchpad/src/org/apache/poi/hslf/usermodel/SlideShow.java b/src/scratchpad/src/org/apache/poi/hslf/usermodel/SlideShow.java
index 6414d177ce..1c21036512 100644
--- a/src/scratchpad/src/org/apache/poi/hslf/usermodel/SlideShow.java
+++ b/src/scratchpad/src/org/apache/poi/hslf/usermodel/SlideShow.java
@@ -739,7 +739,6 @@ public final class SlideShow {
byte[] uid = PictureData.getChecksum(data);
EscherContainerRecord bstore;
- int offset = 0;
EscherContainerRecord dggContainer = _documentRecord.getPPDrawingGroup().getDggContainer();
bstore = (EscherContainerRecord)Shape.getEscherChild(dggContainer, EscherContainerRecord.BSTORE_CONTAINER);
@@ -763,13 +762,13 @@ public final class SlideShow {
if (Arrays.equals(bse.getUid(), uid)){
return i + 1;
}
- offset += bse.getSize();
}
}
PictureData pict = PictureData.create(format);
pict.setData(data);
- pict.setOffset(offset);
+
+ int offset = _hslfSlideShow.addPicture(pict);
EscherBSERecord bse = new EscherBSERecord();
bse.setRecordId(EscherBSERecord.RECORD_ID);
@@ -786,13 +785,12 @@ public final class SlideShow {
bse.setRef(0);
bse.setOffset(offset);
+ bse.setRemainingData( new byte[0] );
bstore.addChildRecord(bse);
int count = bstore.getChildRecords().size();
bstore.setOptions((short)( (count << 4) | 0xF ));
- _hslfSlideShow.addPicture(pict);
-
return count;
}
diff --git a/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestPictures.java b/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestPictures.java
index 78458f0630..2944a74664 100644
--- a/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestPictures.java
+++ b/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestPictures.java
@@ -436,7 +436,21 @@ public class TestPictures extends TestCase{
pdata = pict.getPictureData();
assertTrue(pdata instanceof WMF);
assertEquals(Picture.WMF, pdata.getType());
- }
+
+ //add a new picture, it should be correctly appended to the Pictures stream
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ for(PictureData p : pictures) p.write(out);
+ out.close();
+
+ int streamSize = out.size();
+
+ PictureData data = PictureData.create(Picture.JPEG);
+ data.setData(new byte[100]);
+ int offset = hslf.addPicture(data);
+ assertEquals(streamSize, offset);
+ assertEquals(3, ppt.getPictureData().length);
+
+ }
public void testGetPictureName() throws Exception {
SlideShow ppt = new SlideShow(new HSLFSlideShow(new File(cwd, "ppt_with_png.ppt").getPath()));