Support for getting OLE object data from slide show. See Bug 43247 for details.
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@573872 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
f52957b77d
commit
a82e65ea7b
@ -20,28 +20,37 @@
|
|||||||
|
|
||||||
package org.apache.poi.hslf;
|
package org.apache.poi.hslf;
|
||||||
|
|
||||||
import java.util.*;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.*;
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Hashtable;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import org.apache.poi.POIDocument;
|
import org.apache.poi.POIDocument;
|
||||||
import org.apache.poi.util.LittleEndian;
|
|
||||||
import org.apache.poi.util.POILogger;
|
|
||||||
import org.apache.poi.util.POILogFactory;
|
|
||||||
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
|
|
||||||
import org.apache.poi.poifs.filesystem.DocumentEntry;
|
|
||||||
import org.apache.poi.poifs.filesystem.DocumentInputStream;
|
|
||||||
|
|
||||||
import org.apache.poi.hpsf.PropertySet;
|
|
||||||
import org.apache.poi.hpsf.PropertySetFactory;
|
|
||||||
import org.apache.poi.hpsf.MutablePropertySet;
|
|
||||||
import org.apache.poi.hpsf.SummaryInformation;
|
|
||||||
import org.apache.poi.hpsf.DocumentSummaryInformation;
|
|
||||||
|
|
||||||
import org.apache.poi.hslf.exceptions.CorruptPowerPointFileException;
|
import org.apache.poi.hslf.exceptions.CorruptPowerPointFileException;
|
||||||
import org.apache.poi.hslf.exceptions.EncryptedPowerPointFileException;
|
import org.apache.poi.hslf.exceptions.EncryptedPowerPointFileException;
|
||||||
import org.apache.poi.hslf.exceptions.HSLFException;
|
import org.apache.poi.hslf.exceptions.HSLFException;
|
||||||
import org.apache.poi.hslf.record.*;
|
import org.apache.poi.hslf.record.CurrentUserAtom;
|
||||||
|
import org.apache.poi.hslf.record.ExOleObjStg;
|
||||||
|
import org.apache.poi.hslf.record.PersistPtrHolder;
|
||||||
|
import org.apache.poi.hslf.record.PositionDependentRecord;
|
||||||
|
import org.apache.poi.hslf.record.Record;
|
||||||
|
import org.apache.poi.hslf.record.UserEditAtom;
|
||||||
|
import org.apache.poi.hslf.usermodel.ObjectData;
|
||||||
import org.apache.poi.hslf.usermodel.PictureData;
|
import org.apache.poi.hslf.usermodel.PictureData;
|
||||||
|
import org.apache.poi.poifs.filesystem.DocumentEntry;
|
||||||
|
import org.apache.poi.poifs.filesystem.DocumentInputStream;
|
||||||
|
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
|
||||||
|
import org.apache.poi.util.LittleEndian;
|
||||||
|
import org.apache.poi.util.POILogFactory;
|
||||||
|
import org.apache.poi.util.POILogger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class contains the main functionality for the Powerpoint file
|
* This class contains the main functionality for the Powerpoint file
|
||||||
@ -68,8 +77,11 @@ public class HSLFSlideShow extends POIDocument
|
|||||||
|
|
||||||
// Raw Pictures contained in the pictures stream
|
// Raw Pictures contained in the pictures stream
|
||||||
private PictureData[] _pictures;
|
private PictureData[] _pictures;
|
||||||
|
|
||||||
/**
|
// Embedded objects stored in storage records in the document stream, lazily populated.
|
||||||
|
private ObjectData[] _objects;
|
||||||
|
|
||||||
|
/**
|
||||||
* Returns the underlying POIFSFileSystem for the document
|
* Returns the underlying POIFSFileSystem for the document
|
||||||
* that is open.
|
* that is open.
|
||||||
*/
|
*/
|
||||||
@ -507,4 +519,22 @@ public class HSLFSlideShow extends POIDocument
|
|||||||
public PictureData[] getPictures() {
|
public PictureData[] getPictures() {
|
||||||
return _pictures;
|
return _pictures;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets embedded object data from the slide show.
|
||||||
|
*
|
||||||
|
* @return the embedded objects.
|
||||||
|
*/
|
||||||
|
public ObjectData[] getEmbeddedObjects() {
|
||||||
|
if (_objects == null) {
|
||||||
|
List objects = new ArrayList();
|
||||||
|
for (int i = 0; i < _records.length; i++) {
|
||||||
|
if (_records[i] instanceof ExOleObjStg) {
|
||||||
|
objects.add(new ObjectData((ExOleObjStg) _records[i]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_objects = (ObjectData[]) objects.toArray(new ObjectData[objects.size()]);
|
||||||
|
}
|
||||||
|
return _objects;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -111,4 +111,12 @@ public class CString extends RecordAtom {
|
|||||||
// Write out our text
|
// Write out our text
|
||||||
out.write(_text);
|
out.write(_text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a string representation of this object, primarily for debugging.
|
||||||
|
* @return a string representation of this object.
|
||||||
|
*/
|
||||||
|
public String toString() {
|
||||||
|
return getText();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
188
src/scratchpad/src/org/apache/poi/hslf/record/ExEmbed.java
Normal file
188
src/scratchpad/src/org/apache/poi/hslf/record/ExEmbed.java
Normal file
@ -0,0 +1,188 @@
|
|||||||
|
/* ====================================================================
|
||||||
|
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
contributor license agreements. See the NOTICE file distributed with
|
||||||
|
this work for additional information regarding copyright ownership.
|
||||||
|
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
(the "License"); you may not use this file except in compliance with
|
||||||
|
the License. You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
==================================================================== */
|
||||||
|
|
||||||
|
package org.apache.poi.hslf.record;
|
||||||
|
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import org.apache.poi.util.LittleEndian;
|
||||||
|
import org.apache.poi.util.POILogger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This data represents an embedded object in the document.
|
||||||
|
*
|
||||||
|
* @author Daniel Noll
|
||||||
|
*/
|
||||||
|
public class ExEmbed extends RecordContainer {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Record header data.
|
||||||
|
*/
|
||||||
|
private byte[] _header;
|
||||||
|
|
||||||
|
// Links to our more interesting children
|
||||||
|
private ExEmbedAtom embedAtom;
|
||||||
|
private ExOleObjAtom oleObjAtom;
|
||||||
|
private CString menuName;
|
||||||
|
private CString progId;
|
||||||
|
private CString clipboardName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set things up, and find our more interesting children
|
||||||
|
*
|
||||||
|
* @param source the source data as a byte array.
|
||||||
|
* @param start the start offset into the byte array.
|
||||||
|
* @param len the length of the slice in the byte array.
|
||||||
|
*/
|
||||||
|
protected ExEmbed(byte[] source, int start, int len) {
|
||||||
|
// Grab the header
|
||||||
|
_header = new byte[8];
|
||||||
|
System.arraycopy(source,start,_header,0,8);
|
||||||
|
|
||||||
|
// Find our children
|
||||||
|
_children = Record.findChildRecords(source,start+8,len-8);
|
||||||
|
findInterestingChildren();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new ExEmbed, with blank fields
|
||||||
|
*/
|
||||||
|
public ExEmbed() {
|
||||||
|
_header = new byte[8];
|
||||||
|
_children = new Record[5];
|
||||||
|
|
||||||
|
// Setup our header block
|
||||||
|
_header[0] = 0x0f; // We are a container record
|
||||||
|
LittleEndian.putShort(_header, 2, (short)getRecordType());
|
||||||
|
|
||||||
|
// Setup our child records
|
||||||
|
CString cs1 = new CString();
|
||||||
|
CString cs2 = new CString();
|
||||||
|
CString cs3 = new CString();
|
||||||
|
// cs1.setCount(0x00);
|
||||||
|
// cs2.setCount(0x10);
|
||||||
|
_children[0] = new ExEmbedAtom();
|
||||||
|
_children[1] = new ExOleObjAtom();
|
||||||
|
_children[2] = cs1;
|
||||||
|
_children[3] = cs2;
|
||||||
|
_children[4] = cs3;
|
||||||
|
findInterestingChildren();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Go through our child records, picking out the ones that are
|
||||||
|
* interesting, and saving those for use by the easy helper methods.
|
||||||
|
*/
|
||||||
|
private void findInterestingChildren() {
|
||||||
|
|
||||||
|
// First child should be the ExHyperlinkAtom
|
||||||
|
if(_children[0] instanceof ExEmbedAtom) {
|
||||||
|
embedAtom = (ExEmbedAtom)_children[0];
|
||||||
|
} else {
|
||||||
|
logger.log(POILogger.ERROR, "First child record wasn't a ExEmbedAtom, was of type " + _children[0].getRecordType());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Second child should be the ExOleObjAtom
|
||||||
|
if (_children[1] instanceof ExOleObjAtom) {
|
||||||
|
oleObjAtom = (ExOleObjAtom)_children[1];
|
||||||
|
} else {
|
||||||
|
logger.log(POILogger.ERROR, "Second child record wasn't a ExOleObjAtom, was of type " + _children[1].getRecordType());
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 2; i < _children.length; i++) {
|
||||||
|
if (_children[i] instanceof CString){
|
||||||
|
if (menuName == null) menuName = (CString)_children[i];
|
||||||
|
else if (progId == null) progId = (CString)_children[i];
|
||||||
|
else if (clipboardName == null) clipboardName = (CString)_children[i];
|
||||||
|
} else {
|
||||||
|
logger.log(POILogger.ERROR, "Record after atoms wasn't a CString, was of type " + _children[i].getRecordType());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the {@code ExEmbedAtom}.
|
||||||
|
*
|
||||||
|
* @return the {@code ExEmbedAtom}.
|
||||||
|
*/
|
||||||
|
public ExEmbedAtom getExEmbedAtom()
|
||||||
|
{
|
||||||
|
return embedAtom;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the {@code ExOleObjAtom}.
|
||||||
|
*
|
||||||
|
* @return the {@code ExOleObjAtom}.
|
||||||
|
*/
|
||||||
|
public ExOleObjAtom getExOleObjAtom()
|
||||||
|
{
|
||||||
|
return oleObjAtom;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the name used for menus and the Links dialog box.
|
||||||
|
*
|
||||||
|
* @return the name used for menus and the Links dialog box.
|
||||||
|
*/
|
||||||
|
public String getMenuName()
|
||||||
|
{
|
||||||
|
return menuName == null ? null : menuName.getText();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the OLE Programmatic Identifier.
|
||||||
|
*
|
||||||
|
* @return the OLE Programmatic Identifier.
|
||||||
|
*/
|
||||||
|
public String getProgId()
|
||||||
|
{
|
||||||
|
return progId == null ? null : progId.getText();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the name that appears in the paste special dialog.
|
||||||
|
*
|
||||||
|
* @return the name that appears in the paste special dialog.
|
||||||
|
*/
|
||||||
|
public String getClipboardName()
|
||||||
|
{
|
||||||
|
return clipboardName == null ? null : clipboardName.getText();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the type (held as a little endian in bytes 3 and 4)
|
||||||
|
* that this class handles.
|
||||||
|
*
|
||||||
|
* @return the record type.
|
||||||
|
*/
|
||||||
|
public long getRecordType() {
|
||||||
|
return RecordTypes.ExEmbed.typeID;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Have the contents printer out into an OutputStream, used when
|
||||||
|
* writing a file back out to disk.
|
||||||
|
*
|
||||||
|
* @param out the output stream.
|
||||||
|
* @throws IOException if there was an error writing to the stream.
|
||||||
|
*/
|
||||||
|
public void writeOut(OutputStream out) throws IOException {
|
||||||
|
writeOut(_header[0],_header[1],getRecordType(),_children,out);
|
||||||
|
}
|
||||||
|
}
|
161
src/scratchpad/src/org/apache/poi/hslf/record/ExEmbedAtom.java
Normal file
161
src/scratchpad/src/org/apache/poi/hslf/record/ExEmbedAtom.java
Normal file
@ -0,0 +1,161 @@
|
|||||||
|
/* ====================================================================
|
||||||
|
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
contributor license agreements. See the NOTICE file distributed with
|
||||||
|
this work for additional information regarding copyright ownership.
|
||||||
|
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
(the "License"); you may not use this file except in compliance with
|
||||||
|
the License. You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
==================================================================== */
|
||||||
|
|
||||||
|
package org.apache.poi.hslf.record;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
import org.apache.poi.util.LittleEndian;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The atom that holds metadata on a specific embedded object in the document.
|
||||||
|
*
|
||||||
|
* <!--
|
||||||
|
* 0 sint4 followColorScheme This field indicates how the object follows the color scheme. Valid values are:
|
||||||
|
* 0 - doesn't follow the color scheme
|
||||||
|
* 1 - follows the entire color scheme
|
||||||
|
* 2 - follows the text and background scheme
|
||||||
|
*
|
||||||
|
* 4 bool1 cantLockServerB Set if the embedded server can not be locked
|
||||||
|
* 5 bool1 noSizeToServerB Set if don't need to send the dimension to the embedded object
|
||||||
|
* 6 Bool1 isTable Set if the object is a Word table
|
||||||
|
* -->
|
||||||
|
*
|
||||||
|
* @author Daniel Noll
|
||||||
|
*/
|
||||||
|
public class ExEmbedAtom extends RecordAtom {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Embedded document does not follow the color scheme.
|
||||||
|
*/
|
||||||
|
public static final int DOES_NOT_FOLLOW_COLOR_SCHEME = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Embedded document follows the entire color scheme.
|
||||||
|
*/
|
||||||
|
public static final int FOLLOWS_ENTIRE_COLOR_SCHEME = 1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Embedded document follows the text and background scheme.
|
||||||
|
*/
|
||||||
|
public static final int FOLLOWS_TEXT_AND_BACKGROUND_SCHEME = 2;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Record header.
|
||||||
|
*/
|
||||||
|
private byte[] _header;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Record data.
|
||||||
|
*/
|
||||||
|
private byte[] _data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a brand new embedded object atom record.
|
||||||
|
*/
|
||||||
|
protected ExEmbedAtom() {
|
||||||
|
_header = new byte[8];
|
||||||
|
_data = new byte[7];
|
||||||
|
|
||||||
|
LittleEndian.putShort(_header, 2, (short)getRecordType());
|
||||||
|
LittleEndian.putInt(_header, 4, _data.length);
|
||||||
|
|
||||||
|
// It is fine for the other values to be zero
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs the embedded object atom record from its source data.
|
||||||
|
*
|
||||||
|
* @param source the source data as a byte array.
|
||||||
|
* @param start the start offset into the byte array.
|
||||||
|
* @param len the length of the slice in the byte array.
|
||||||
|
*/
|
||||||
|
protected ExEmbedAtom(byte[] source, int start, int len) {
|
||||||
|
// Get the header.
|
||||||
|
_header = new byte[8];
|
||||||
|
System.arraycopy(source,start,_header,0,8);
|
||||||
|
|
||||||
|
// Get the record data.
|
||||||
|
_data = new byte[len-8];
|
||||||
|
System.arraycopy(source,start+8,_data,0,len-8);
|
||||||
|
|
||||||
|
// Must be at least 4 bytes long
|
||||||
|
if(_data.length < 7) {
|
||||||
|
throw new IllegalArgumentException("The length of the data for a ExEmbedAtom must be at least 4 bytes, but was only " + _data.length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets whether the object follows the color scheme.
|
||||||
|
*
|
||||||
|
* @return one of {@link #DOES_NOT_FOLLOW_COLOR_SCHEME},
|
||||||
|
* {@link #FOLLOWS_ENTIRE_COLOR_SCHEME}, or
|
||||||
|
* {@link #FOLLOWS_TEXT_AND_BACKGROUND_SCHEME}.
|
||||||
|
*/
|
||||||
|
public int getFollowColorScheme() {
|
||||||
|
return LittleEndian.getInt(_data, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets whether the embedded server cannot be locked.
|
||||||
|
*
|
||||||
|
* @return {@code true} if the embedded server cannot be locked.
|
||||||
|
*/
|
||||||
|
public boolean getCantLockServerB() {
|
||||||
|
return _data[4] != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets whether it is not required to send the dimensions to the embedded object.
|
||||||
|
*
|
||||||
|
* @return {@code true} if the embedded server does not require the object dimensions.
|
||||||
|
*/
|
||||||
|
public boolean getNoSizeToServerB() {
|
||||||
|
return _data[5] != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Getswhether the object is a Word table.
|
||||||
|
*
|
||||||
|
* @return {@code true} if the object is a Word table.
|
||||||
|
*/
|
||||||
|
public boolean getIsTable() {
|
||||||
|
return _data[6] != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the record type.
|
||||||
|
* @return the record type.
|
||||||
|
*/
|
||||||
|
public long getRecordType() {
|
||||||
|
return RecordTypes.ExEmbedAtom.typeID;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write the contents of the record back, so it can be written
|
||||||
|
* to disk
|
||||||
|
*
|
||||||
|
* @param out the output stream to write to.
|
||||||
|
* @throws IOException if an error occurs.
|
||||||
|
*/
|
||||||
|
public void writeOut(OutputStream out) throws IOException {
|
||||||
|
out.write(_header);
|
||||||
|
out.write(_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
213
src/scratchpad/src/org/apache/poi/hslf/record/ExOleObjAtom.java
Normal file
213
src/scratchpad/src/org/apache/poi/hslf/record/ExOleObjAtom.java
Normal file
@ -0,0 +1,213 @@
|
|||||||
|
/* ====================================================================
|
||||||
|
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
contributor license agreements. See the NOTICE file distributed with
|
||||||
|
this work for additional information regarding copyright ownership.
|
||||||
|
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
(the "License"); you may not use this file except in compliance with
|
||||||
|
the License. You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
==================================================================== */
|
||||||
|
|
||||||
|
package org.apache.poi.hslf.record;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
import org.apache.poi.util.LittleEndian;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Atom storing information for an OLE object.
|
||||||
|
*
|
||||||
|
* <!--
|
||||||
|
* offset type name description
|
||||||
|
*
|
||||||
|
* 0 uint4 drawAspect Stores whether the object can be completely seen
|
||||||
|
* (value of 1), or if only the icon is visible (value of 4).
|
||||||
|
*
|
||||||
|
* 4 sint4 type Specifies whether the object is embedded or linked.
|
||||||
|
* 0 - embedded
|
||||||
|
* 1 - linked
|
||||||
|
*
|
||||||
|
* 8 sint4 objID Unique identifier for the OLE object
|
||||||
|
*
|
||||||
|
* 2 sint4 subType This specifies the type of ole object.
|
||||||
|
* 0 - Default object
|
||||||
|
* 1 - Microsoft Clipart Gallery
|
||||||
|
* 2 - Microsoft Word table
|
||||||
|
* 3 - Microsoft Excel
|
||||||
|
* 4 - Microsoft Graph
|
||||||
|
* 5 - Microsoft Organization Chart
|
||||||
|
* 6 - Microsoft Equation Editor
|
||||||
|
* 7 - Microsoft Wordart object
|
||||||
|
* 8 - Sound
|
||||||
|
* 9 - Image
|
||||||
|
* 10 - PowerPoint presentation
|
||||||
|
* 11 - PowerPoint slide
|
||||||
|
* 12 - Microsoft Project
|
||||||
|
* 13 - Microsoft Note-It Ole
|
||||||
|
* 14 - Microsoft Excel chart
|
||||||
|
* 15 - Media Player object
|
||||||
|
*
|
||||||
|
* 16 sint4 objStgDataRef Reference to persist object
|
||||||
|
*
|
||||||
|
* 20 bool1 isBlank Set if the object's image is blank
|
||||||
|
* (note: KOffice has this as an int.)
|
||||||
|
* -->
|
||||||
|
*
|
||||||
|
* @author Daniel Noll
|
||||||
|
*/
|
||||||
|
public class ExOleObjAtom extends RecordAtom {
|
||||||
|
|
||||||
|
public static final int DRAW_ASPECT_VISIBLE = 1;
|
||||||
|
public static final int DRAW_ASPECT_ICON = 4;
|
||||||
|
|
||||||
|
public static final int TYPE_EMBEDDED = 0;
|
||||||
|
public static final int TYPE_LINKED = 1;
|
||||||
|
|
||||||
|
public static final int SUBTYPE_DEFAULT = 0;
|
||||||
|
public static final int SUBTYPE_CLIPART_GALLERY = 1;
|
||||||
|
public static final int SUBTYPE_WORD_TABLE = 2;
|
||||||
|
public static final int SUBTYPE_EXCEL = 3;
|
||||||
|
public static final int SUBTYPE_GRAPH = 4;
|
||||||
|
public static final int SUBTYPE_ORGANIZATION_CHART = 5;
|
||||||
|
public static final int SUBTYPE_EQUATION = 6;
|
||||||
|
public static final int SUBTYPE_WORDART = 7;
|
||||||
|
public static final int SUBTYPE_SOUND = 8;
|
||||||
|
public static final int SUBTYPE_IMAGE = 9;
|
||||||
|
public static final int SUBTYPE_POWERPOINT_PRESENTATION = 10;
|
||||||
|
public static final int SUBTYPE_POWERPOINT_SLIDE = 11;
|
||||||
|
public static final int SUBTYPE_PROJECT = 12;
|
||||||
|
public static final int SUBTYPE_NOTEIT = 13;
|
||||||
|
public static final int SUBTYPE_EXCEL_CHART = 14;
|
||||||
|
public static final int SUBTYPE_MEDIA_PLAYER = 15;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Record header.
|
||||||
|
*/
|
||||||
|
private byte[] _header;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Record data.
|
||||||
|
*/
|
||||||
|
private byte[] _data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a brand new link related atom record.
|
||||||
|
*/
|
||||||
|
protected ExOleObjAtom() {
|
||||||
|
_header = new byte[8];
|
||||||
|
_data = new byte[18];
|
||||||
|
|
||||||
|
LittleEndian.putShort(_header, 2, (short)getRecordType());
|
||||||
|
LittleEndian.putInt(_header, 4, _data.length);
|
||||||
|
|
||||||
|
// I hope it is fine for the other values to be zero.
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs the link related atom record from its
|
||||||
|
* source data.
|
||||||
|
*
|
||||||
|
* @param source the source data as a byte array.
|
||||||
|
* @param start the start offset into the byte array.
|
||||||
|
* @param len the length of the slice in the byte array.
|
||||||
|
*/
|
||||||
|
protected ExOleObjAtom(byte[] source, int start, int len) {
|
||||||
|
// Get the header.
|
||||||
|
_header = new byte[8];
|
||||||
|
System.arraycopy(source,start,_header,0,8);
|
||||||
|
|
||||||
|
// Get the record data.
|
||||||
|
_data = new byte[len-8];
|
||||||
|
System.arraycopy(source,start+8,_data,0,len-8);
|
||||||
|
|
||||||
|
// Must be at least 24 bytes long
|
||||||
|
if(_data.length < 24) {
|
||||||
|
throw new IllegalArgumentException("The length of the data for a ExOleObjAtom must be at least 24 bytes, but was only " + _data.length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets whether the object can be completely seen, or if only the
|
||||||
|
* icon is visible.
|
||||||
|
*
|
||||||
|
* @return the draw aspect, one of the {@code DRAW_ASPECT_*} constants.
|
||||||
|
*/
|
||||||
|
public int getDrawAspect() {
|
||||||
|
return LittleEndian.getInt(_data, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets whether the object is embedded or linked.
|
||||||
|
*
|
||||||
|
* @return the type, one of the {@code TYPE_EMBEDDED_*} constants.
|
||||||
|
*/
|
||||||
|
public int getType() {
|
||||||
|
return LittleEndian.getInt(_data, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the unique identifier for the OLE object.
|
||||||
|
*
|
||||||
|
* @return the object ID.
|
||||||
|
*/
|
||||||
|
public int getObjID() {
|
||||||
|
return LittleEndian.getInt(_data, 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the type of OLE object.
|
||||||
|
*
|
||||||
|
* @return the sub-type, one of the {@code SUBTYPE_*} constants.
|
||||||
|
*/
|
||||||
|
public int getSubType() {
|
||||||
|
return LittleEndian.getInt(_data, 12);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the reference to the persistent object
|
||||||
|
*
|
||||||
|
* @return the reference to the persistent object, corresponds with an
|
||||||
|
* {@code ExOleObjStg} storage container.
|
||||||
|
*/
|
||||||
|
public int getObjStgDataRef() {
|
||||||
|
return LittleEndian.getInt(_data, 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets whether the object's image is blank.
|
||||||
|
*
|
||||||
|
* @return {@code true} if the object's image is blank.
|
||||||
|
*/
|
||||||
|
public boolean getIsBlank() {
|
||||||
|
// Even though this is a mere boolean, KOffice's code says it's an int.
|
||||||
|
return LittleEndian.getInt(_data, 20) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the type (held as a little endian in bytes 3 and 4)
|
||||||
|
* that this class handles.
|
||||||
|
*/
|
||||||
|
public long getRecordType() {
|
||||||
|
return RecordTypes.ExOleObjAtom.typeID;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Have the contents printer out into an OutputStream, used when
|
||||||
|
* writing a file back out to disk
|
||||||
|
* (Normally, atom classes will keep their bytes around, but
|
||||||
|
* non atom classes will just request the bytes from their
|
||||||
|
* children, then chuck on their header and return)
|
||||||
|
*/
|
||||||
|
public void writeOut(OutputStream out) throws IOException {
|
||||||
|
out.write(_header);
|
||||||
|
out.write(_data);
|
||||||
|
}
|
||||||
|
}
|
112
src/scratchpad/src/org/apache/poi/hslf/record/ExOleObjStg.java
Normal file
112
src/scratchpad/src/org/apache/poi/hslf/record/ExOleObjStg.java
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
/* ====================================================================
|
||||||
|
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
contributor license agreements. See the NOTICE file distributed with
|
||||||
|
this work for additional information regarding copyright ownership.
|
||||||
|
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
(the "License"); you may not use this file except in compliance with
|
||||||
|
the License. You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
==================================================================== */
|
||||||
|
|
||||||
|
package org.apache.poi.hslf.record;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.util.zip.InflaterInputStream;
|
||||||
|
|
||||||
|
import org.apache.poi.util.LittleEndian;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Storage for embedded OLE objects.
|
||||||
|
*
|
||||||
|
* @author Daniel Noll
|
||||||
|
*/
|
||||||
|
public class ExOleObjStg extends RecordAtom {
|
||||||
|
/**
|
||||||
|
* Record header.
|
||||||
|
*/
|
||||||
|
private byte[] _header;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Record data.
|
||||||
|
*/
|
||||||
|
private byte[] _data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new empty storage container.
|
||||||
|
*/
|
||||||
|
protected ExOleObjStg() {
|
||||||
|
_header = new byte[8];
|
||||||
|
_data = new byte[0];
|
||||||
|
|
||||||
|
LittleEndian.putShort(_header, 2, (short)getRecordType());
|
||||||
|
LittleEndian.putInt(_header, 4, _data.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs the link related atom record from its
|
||||||
|
* source data.
|
||||||
|
*
|
||||||
|
* @param source the source data as a byte array.
|
||||||
|
* @param start the start offset into the byte array.
|
||||||
|
* @param len the length of the slice in the byte array.
|
||||||
|
*/
|
||||||
|
protected ExOleObjStg(byte[] source, int start, int len) {
|
||||||
|
// Get the header.
|
||||||
|
_header = new byte[8];
|
||||||
|
System.arraycopy(source,start,_header,0,8);
|
||||||
|
|
||||||
|
// Get the record data.
|
||||||
|
_data = new byte[len-8];
|
||||||
|
System.arraycopy(source,start+8,_data,0,len-8);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the uncompressed length of the data.
|
||||||
|
*
|
||||||
|
* @return the uncompressed length of the data.
|
||||||
|
*/
|
||||||
|
public int getDataLength() {
|
||||||
|
return LittleEndian.getInt(_data, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Opens an input stream which will decompress the data on the fly.
|
||||||
|
*
|
||||||
|
* @return the data input stream.
|
||||||
|
*/
|
||||||
|
public InputStream getData() {
|
||||||
|
InputStream compressedStream = new ByteArrayInputStream(_data, 4, _data.length);
|
||||||
|
return new InflaterInputStream(compressedStream);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the record type.
|
||||||
|
*
|
||||||
|
* @return the record type.
|
||||||
|
*/
|
||||||
|
public long getRecordType() {
|
||||||
|
return RecordTypes.ExOleObjStg.typeID;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write the contents of the record back, so it can be written
|
||||||
|
* to disk.
|
||||||
|
*
|
||||||
|
* @param out the output stream to write to.
|
||||||
|
* @throws IOException if an error occurs.
|
||||||
|
*/
|
||||||
|
public void writeOut(OutputStream out) throws IOException {
|
||||||
|
out.write(_header);
|
||||||
|
out.write(_data);
|
||||||
|
}
|
||||||
|
}
|
@ -98,11 +98,11 @@ public class RecordTypes {
|
|||||||
public static final Type FontEmbeddedData = new Type(4024,null);
|
public static final Type FontEmbeddedData = new Type(4024,null);
|
||||||
public static final Type CString = new Type(4026,CString.class);
|
public static final Type CString = new Type(4026,CString.class);
|
||||||
public static final Type MetaFile = new Type(4033,null);
|
public static final Type MetaFile = new Type(4033,null);
|
||||||
public static final Type ExOleObjAtom = new Type(4035,null);
|
public static final Type ExOleObjAtom = new Type(4035,ExOleObjAtom.class);
|
||||||
public static final Type SrKinsoku = new Type(4040,null);
|
public static final Type SrKinsoku = new Type(4040,null);
|
||||||
public static final Type HandOut = new Type(4041,null);
|
public static final Type HandOut = new Type(4041,null);
|
||||||
public static final Type ExEmbed = new Type(4044,null);
|
public static final Type ExEmbed = new Type(4044,ExEmbed.class);
|
||||||
public static final Type ExEmbedAtom = new Type(4045,null);
|
public static final Type ExEmbedAtom = new Type(4045,ExEmbedAtom.class);
|
||||||
public static final Type ExLink = new Type(4046,null);
|
public static final Type ExLink = new Type(4046,null);
|
||||||
public static final Type BookmarkEntityAtom = new Type(4048,null);
|
public static final Type BookmarkEntityAtom = new Type(4048,null);
|
||||||
public static final Type ExLinkAtom = new Type(4049,null);
|
public static final Type ExLinkAtom = new Type(4049,null);
|
||||||
@ -136,7 +136,7 @@ public class RecordTypes {
|
|||||||
public static final Type ExCDAudio = new Type(4110,null);
|
public static final Type ExCDAudio = new Type(4110,null);
|
||||||
public static final Type ExWAVAudioEmbedded = new Type(4111,null);
|
public static final Type ExWAVAudioEmbedded = new Type(4111,null);
|
||||||
public static final Type ExWAVAudioLink = new Type(4112,null);
|
public static final Type ExWAVAudioLink = new Type(4112,null);
|
||||||
public static final Type ExOleObjStg = new Type(4113,null);
|
public static final Type ExOleObjStg = new Type(4113,ExOleObjStg.class);
|
||||||
public static final Type ExCDAudioAtom = new Type(4114,null);
|
public static final Type ExCDAudioAtom = new Type(4114,null);
|
||||||
public static final Type ExWAVAudioEmbeddedAtom = new Type(4115,null);
|
public static final Type ExWAVAudioEmbeddedAtom = new Type(4115,null);
|
||||||
public static final Type AnimationInfoAtom = new Type(4116,null);
|
public static final Type AnimationInfoAtom = new Type(4116,null);
|
||||||
|
@ -0,0 +1,51 @@
|
|||||||
|
/* ====================================================================
|
||||||
|
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
contributor license agreements. See the NOTICE file distributed with
|
||||||
|
this work for additional information regarding copyright ownership.
|
||||||
|
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
(the "License"); you may not use this file except in compliance with
|
||||||
|
the License. You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
==================================================================== */
|
||||||
|
package org.apache.poi.hslf.usermodel;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
|
import org.apache.poi.hslf.record.ExOleObjStg;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A class that represents object data embedded in a slide show.
|
||||||
|
*
|
||||||
|
* @author Daniel Noll
|
||||||
|
*/
|
||||||
|
public class ObjectData {
|
||||||
|
/**
|
||||||
|
* The record that contains the object data.
|
||||||
|
*/
|
||||||
|
private ExOleObjStg storage;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates the object data wrapping the record that contains the object data.
|
||||||
|
*
|
||||||
|
* @param storage the record that contains the object data.
|
||||||
|
*/
|
||||||
|
public ObjectData(ExOleObjStg storage) {
|
||||||
|
this.storage = storage;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets an input stream which returns the binary of the embedded data.
|
||||||
|
*
|
||||||
|
* @return the input stream which will contain the binary of the embedded data.
|
||||||
|
*/
|
||||||
|
public InputStream getData() {
|
||||||
|
return storage.getData();
|
||||||
|
}
|
||||||
|
}
|
Binary file not shown.
@ -0,0 +1,62 @@
|
|||||||
|
|
||||||
|
/* ====================================================================
|
||||||
|
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
contributor license agreements. See the NOTICE file distributed with
|
||||||
|
this work for additional information regarding copyright ownership.
|
||||||
|
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
(the "License"); you may not use this file except in compliance with
|
||||||
|
the License. You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
==================================================================== */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
package org.apache.poi.hslf.model;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
|
||||||
|
import org.apache.poi.hslf.HSLFSlideShow;
|
||||||
|
import org.apache.poi.hslf.usermodel.ObjectData;
|
||||||
|
import org.apache.poi.hslf.usermodel.PictureData;
|
||||||
|
|
||||||
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
|
public class TestOleEmbedding extends TestCase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Tests support for OLE objects.
|
||||||
|
*
|
||||||
|
* @throws Exception if an error occurs.
|
||||||
|
*/
|
||||||
|
public void testOleEmbedding2003() throws Exception
|
||||||
|
{
|
||||||
|
String dirname = System.getProperty("HSLF.testdata.path");
|
||||||
|
File file = new File(dirname, "ole2-embedding-2003.ppt");
|
||||||
|
HSLFSlideShow slideShow = new HSLFSlideShow(new FileInputStream(file));
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Placeholder EMFs for clients that don't support the OLE components.
|
||||||
|
PictureData[] pictures = slideShow.getPictures();
|
||||||
|
assertEquals("Should be two pictures", 2, pictures.length);
|
||||||
|
//assertDigestEquals("Wrong data for picture 1", "8d1fbadf4814f321bb1ccdd056e3c788", pictures[0].getData());
|
||||||
|
//assertDigestEquals("Wrong data for picture 2", "987a698e83559cf3d38a0deeba1cc63b", pictures[1].getData());
|
||||||
|
|
||||||
|
// Actual embedded objects.
|
||||||
|
ObjectData[] objects = slideShow.getEmbeddedObjects();
|
||||||
|
assertEquals("Should be two objects", 2, objects.length);
|
||||||
|
//assertDigestEquals("Wrong data for objecs 1", "0d1fcc61a83de5c4894dc0c88e9a019d", objects[0].getData());
|
||||||
|
//assertDigestEquals("Wrong data for object 2", "b323604b2003a7299c77c2693b641495", objects[1].getData());
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
slideShow.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user