diff options
author | Yegor Kozlov <yegor@apache.org> | 2008-04-19 11:09:59 +0000 |
---|---|---|
committer | Yegor Kozlov <yegor@apache.org> | 2008-04-19 11:09:59 +0000 |
commit | 489112cf828c97550c0e6e0c617de8c4d3a5b735 (patch) | |
tree | 5435fffac8c6508d093c68ea5d340c1b0c7bd8b2 /src/scratchpad | |
parent | b3ad61e1e9b510326740f16a47ed4ceb7b4cc30c (diff) | |
download | poi-489112cf828c97550c0e6e0c617de8c4d3a5b735.tar.gz poi-489112cf828c97550c0e6e0c617de8c4d3a5b735.zip |
Support for getting embedded sounds from slide show
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@649796 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src/scratchpad')
-rw-r--r-- | src/scratchpad/src/org/apache/poi/hslf/record/RecordTypes.java | 5 | ||||
-rwxr-xr-x | src/scratchpad/src/org/apache/poi/hslf/record/Sound.java | 136 | ||||
-rwxr-xr-x | src/scratchpad/src/org/apache/poi/hslf/record/SoundCollection.java | 73 | ||||
-rwxr-xr-x | src/scratchpad/src/org/apache/poi/hslf/record/SoundData.java | 103 | ||||
-rw-r--r-- | src/scratchpad/src/org/apache/poi/hslf/usermodel/SlideShow.java | 8 | ||||
-rwxr-xr-x | src/scratchpad/src/org/apache/poi/hslf/usermodel/SoundData.java | 93 | ||||
-rwxr-xr-x | src/scratchpad/testcases/org/apache/poi/hslf/data/ringin.wav | bin | 0 -> 10026 bytes | |||
-rwxr-xr-x | src/scratchpad/testcases/org/apache/poi/hslf/data/sound.ppt | bin | 0 -> 43520 bytes | |||
-rwxr-xr-x | src/scratchpad/testcases/org/apache/poi/hslf/record/TestSound.java | 86 | ||||
-rwxr-xr-x | src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestSoundData.java | 63 |
10 files changed, 565 insertions, 2 deletions
diff --git a/src/scratchpad/src/org/apache/poi/hslf/record/RecordTypes.java b/src/scratchpad/src/org/apache/poi/hslf/record/RecordTypes.java index a1bc499453..45038f7a28 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/record/RecordTypes.java +++ b/src/scratchpad/src/org/apache/poi/hslf/record/RecordTypes.java @@ -70,9 +70,10 @@ public class RecordTypes { public static final Type List = new Type(2000,null); public static final Type FontCollection = new Type(2005,FontCollection.class); public static final Type BookmarkCollection = new Type(2019,null); + public static final Type SoundCollection = new Type(2020,SoundCollection.class); public static final Type SoundCollAtom = new Type(2021,null); - public static final Type Sound = new Type(2022,null); - public static final Type SoundData = new Type(2023,null); + public static final Type Sound = new Type(2022,Sound.class); + public static final Type SoundData = new Type(2023,SoundData.class); public static final Type BookmarkSeedAtom = new Type(2025,null); public static final Type ColorSchemeAtom = new Type(2032,ColorSchemeAtom.class); public static final Type ExObjRefAtom = new Type(3009,null); diff --git a/src/scratchpad/src/org/apache/poi/hslf/record/Sound.java b/src/scratchpad/src/org/apache/poi/hslf/record/Sound.java new file mode 100755 index 0000000000..211a9b0ee4 --- /dev/null +++ b/src/scratchpad/src/org/apache/poi/hslf/record/Sound.java @@ -0,0 +1,136 @@ +/* ====================================================================
+ 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 org.apache.poi.util.POILogger;
+
+import java.io.OutputStream;
+import java.io.IOException;
+
+/**
+ * A container holding information about a sound. It contains:
+ * <p>
+ * <li>1. CString (4026), Instance 0: Name of sound (e.g. "crash")
+ * <li>2. CString (4026), Instance 1: Type of sound (e.g. ".wav")
+ * <li>3. CString (4026), Instance 2: Reference id of sound in sound collection
+ * <li>4. CString (4026), Instance 3, optional: Built-in id of sound, for sounds we ship. This is the id that?s in the reg file.
+ * <li>5. SoundData (2023), optional
+ * </p>
+ *
+ * @author Yegor Kozlov
+ */
+public class Sound extends RecordContainer {
+ /**
+ * Record header data.
+ */
+ private byte[] _header;
+
+ // Links to our more interesting children
+ private CString _name;
+ private CString _type;
+ private SoundData _data;
+
+
+ /**
+ * 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 Sound(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();
+ }
+
+ private void findInterestingChildren() {
+ // First child should be the ExHyperlinkAtom
+ if(_children[0] instanceof CString) {
+ _name = (CString)_children[0];
+ } else {
+ logger.log(POILogger.ERROR, "First child record wasn't a CString, was of type " + _children[0].getRecordType());
+ }
+
+ // Second child should be the ExOleObjAtom
+ if (_children[1] instanceof CString) {
+ _type = (CString)_children[1];
+ } else {
+ logger.log(POILogger.ERROR, "Second child record wasn't a CString, was of type " + _children[1].getRecordType());
+ }
+
+ for (int i = 2; i < _children.length; i++) {
+ if(_children[i] instanceof SoundData){
+ _data = (SoundData)_children[i];
+ break;
+ }
+ }
+
+ }
+
+ /**
+ * 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.Sound.typeID;
+ }
+
+ /**
+ * Have the contents printer out into an OutputStream, used when
+ * writing a file back out to disk.
+ *
+ * @param out the output stream.
+ * @throws java.io.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);
+ }
+
+ /**
+ * Name of the sound (e.g. "crash")
+ *
+ * @return name of the sound
+ */
+ public String getSoundName(){
+ return _name.getText();
+ }
+
+ /**
+ * Type of the sound (e.g. ".wav")
+ *
+ * @return type of the sound
+ */
+ public String getSoundType(){
+ return _type.getText();
+ }
+
+ /**
+ * The sound data
+ *
+ * @return the sound data.
+ */
+ public byte[] getSoundData(){
+ return _data == null ? null : _data.getData();
+ }
+}
diff --git a/src/scratchpad/src/org/apache/poi/hslf/record/SoundCollection.java b/src/scratchpad/src/org/apache/poi/hslf/record/SoundCollection.java new file mode 100755 index 0000000000..c244859ea0 --- /dev/null +++ b/src/scratchpad/src/org/apache/poi/hslf/record/SoundCollection.java @@ -0,0 +1,73 @@ +/* ====================================================================
+ 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 org.apache.poi.util.POILogger;
+
+import java.io.OutputStream;
+import java.io.IOException;
+
+/**
+ * Is a container for all sound related atoms and containers. It contains:
+ *<li>1. SoundCollAtom (2021)
+ *<li>2. Sound (2022), for each sound, if any
+ *
+ * @author Yegor Kozlov
+ */
+public class SoundCollection extends RecordContainer {
+ /**
+ * Record header data.
+ */
+ private byte[] _header;
+
+ /**
+ * 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 SoundCollection(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);
+ }
+
+ /**
+ * 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.SoundCollection.typeID;
+ }
+
+ /**
+ * Have the contents printer out into an OutputStream, used when
+ * writing a file back out to disk.
+ *
+ * @param out the output stream.
+ * @throws java.io.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);
+ }
+}
diff --git a/src/scratchpad/src/org/apache/poi/hslf/record/SoundData.java b/src/scratchpad/src/org/apache/poi/hslf/record/SoundData.java new file mode 100755 index 0000000000..42be48f2ac --- /dev/null +++ b/src/scratchpad/src/org/apache/poi/hslf/record/SoundData.java @@ -0,0 +1,103 @@ +/* ====================================================================
+ 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 sounds.
+ *
+ * @author Yegor Kozlov
+ */
+public class SoundData extends RecordAtom {
+
+ /**
+ * Record header.
+ */
+ private byte[] _header;
+
+ /**
+ * Record data.
+ */
+ private byte[] _data;
+
+ /**
+ * Constructs a new empty sound container.
+ */
+ protected SoundData() {
+ _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 SoundData(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);
+ }
+
+ /**
+ * Returns the sound data.
+ *
+ * @return the sound data
+ */
+ public byte[] getData() {
+ return _data;
+ }
+
+ /**
+ * Gets the record type.
+ *
+ * @return the record type.
+ */
+ public long getRecordType() {
+ return RecordTypes.SoundData.typeID;
+ }
+
+ /**
+ * Write the contents of the record back, so it can be written
+ * to disk.
+ *
+ * @param out the output stream to write to.
+ * @throws java.io.IOException if an error occurs.
+ */
+ public void writeOut(OutputStream out) throws IOException {
+ out.write(_header);
+ out.write(_data);
+ }
+}
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 418dc3d2f0..828255087b 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/usermodel/SlideShow.java +++ b/src/scratchpad/src/org/apache/poi/hslf/usermodel/SlideShow.java @@ -494,6 +494,14 @@ public class SlideShow public ObjectData[] getEmbeddedObjects() { return _hslfSlideShow.getEmbeddedObjects(); } + + /** + * Returns the data of all the embedded sounds in the SlideShow + */ + public SoundData[] getSoundData() { + return SoundData.find(_documentRecord); + } + /** * Return the current page size */ diff --git a/src/scratchpad/src/org/apache/poi/hslf/usermodel/SoundData.java b/src/scratchpad/src/org/apache/poi/hslf/usermodel/SoundData.java new file mode 100755 index 0000000000..ad7922ef61 --- /dev/null +++ b/src/scratchpad/src/org/apache/poi/hslf/usermodel/SoundData.java @@ -0,0 +1,93 @@ +/* ====================================================================
+ 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 org.apache.poi.hslf.record.*;
+
+import java.util.ArrayList;
+
+/**
+ * A class that represents sound data embedded in a slide show.
+ *
+ * @author Yegor Kozlov
+ */
+public class SoundData {
+ /**
+ * The record that contains the object data.
+ */
+ private Sound _container;
+
+ /**
+ * Creates the object data wrapping the record that contains the sound data.
+ *
+ * @param container the record that contains the sound data.
+ */
+ public SoundData(Sound container) {
+ this._container = container;
+ }
+
+ /**
+ * Name of the sound (e.g. "crash")
+ *
+ * @return name of the sound
+ */
+ public String getSoundName(){
+ return _container.getSoundName();
+ }
+
+ /**
+ * Type of the sound (e.g. ".wav")
+ *
+ * @return type of the sound
+ */
+ public String getSoundType(){
+ return _container.getSoundType();
+ }
+
+ /**
+ * Gets an input stream which returns the binary of the sound data.
+ *
+ * @return the input stream which will contain the binary of the sound data.
+ */
+ public byte[] getData() {
+ return _container.getSoundData();
+ }
+
+ /**
+ * Find all sound records in the supplied Document records
+ *
+ * @param document the document to find in
+ * @return the array with the sound data
+ */
+ public static SoundData[] find(Document document){
+ ArrayList lst = new ArrayList();
+ Record[] ch = document.getChildRecords();
+ for (int i = 0; i < ch.length; i++) {
+ if(ch[i].getRecordType() == RecordTypes.SoundCollection.typeID){
+ RecordContainer col = (RecordContainer)ch[i];
+ Record[] sr = col.getChildRecords();
+ for (int j = 0; j < sr.length; j++) {
+ if(sr[j] instanceof Sound){
+ lst.add(new SoundData((Sound)sr[j]));
+ }
+ }
+ }
+
+ }
+ return (SoundData[])lst.toArray(new SoundData[lst.size()]);
+ }
+}
diff --git a/src/scratchpad/testcases/org/apache/poi/hslf/data/ringin.wav b/src/scratchpad/testcases/org/apache/poi/hslf/data/ringin.wav Binary files differnew file mode 100755 index 0000000000..f8d4292d0f --- /dev/null +++ b/src/scratchpad/testcases/org/apache/poi/hslf/data/ringin.wav diff --git a/src/scratchpad/testcases/org/apache/poi/hslf/data/sound.ppt b/src/scratchpad/testcases/org/apache/poi/hslf/data/sound.ppt Binary files differnew file mode 100755 index 0000000000..2d1316acf3 --- /dev/null +++ b/src/scratchpad/testcases/org/apache/poi/hslf/data/sound.ppt diff --git a/src/scratchpad/testcases/org/apache/poi/hslf/record/TestSound.java b/src/scratchpad/testcases/org/apache/poi/hslf/record/TestSound.java new file mode 100755 index 0000000000..97a4b7c5b5 --- /dev/null +++ b/src/scratchpad/testcases/org/apache/poi/hslf/record/TestSound.java @@ -0,0 +1,86 @@ +
+/* ====================================================================
+ 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 junit.framework.TestCase;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.Arrays;
+
+import org.apache.poi.hslf.HSLFSlideShow;
+import org.apache.poi.hslf.usermodel.SlideShow;
+
+/**
+ * Tests Sound-related records: SoundCollection(2020), Sound(2022) and SoundData(2023)).
+ *
+ * @author Yegor Kozlov
+ */
+public class TestSound extends TestCase {
+ public void testRealFile() throws Exception {
+ String cwd = System.getProperty("HSLF.testdata.path");
+ FileInputStream is = new FileInputStream(new File(cwd, "sound.ppt"));
+ SlideShow ppt = new SlideShow(is);
+ is.close();
+
+ // Get the document
+ Document doc = ppt.getDocumentRecord();
+ SoundCollection soundCollection = null;
+ Record[] doc_ch = doc.getChildRecords();
+ for (int i = 0; i < doc_ch.length; i++) {
+ if(doc_ch[i] instanceof SoundCollection){
+ soundCollection = (SoundCollection)doc_ch[i];
+ break;
+ }
+ }
+ assertNotNull(soundCollection);
+
+ Sound sound = null;
+ Record[] sound_ch = soundCollection.getChildRecords();
+ int k = 0;
+ for (int i = 0; i < sound_ch.length; i++) {
+ if(sound_ch[i] instanceof Sound){
+ sound = (Sound)sound_ch[i];
+ k++;
+ }
+ }
+ assertNotNull(sound);
+ assertEquals(1, k);
+
+ assertEquals("ringin.wav", sound.getSoundName());
+ assertEquals(".WAV", sound.getSoundType());
+ assertNotNull(sound.getSoundData());
+
+ File f = new File(cwd, "ringin.wav");
+ int length = (int)f.length();
+ byte[] ref_data = new byte[length];
+ is = new FileInputStream(f);
+ is.read(ref_data);
+ is.close();
+
+ assertTrue(Arrays.equals(ref_data, sound.getSoundData()));
+
+ }
+}
diff --git a/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestSoundData.java b/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestSoundData.java new file mode 100755 index 0000000000..95de38f8ba --- /dev/null +++ b/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestSoundData.java @@ -0,0 +1,63 @@ +/* ====================================================================
+ 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 org.apache.poi.hslf.*;
+import org.apache.poi.hslf.exceptions.HSLFException;
+import org.apache.poi.hslf.blip.*;
+import org.apache.poi.hslf.model.*;
+import junit.framework.TestCase;
+
+import java.io.*;
+import java.util.Arrays;
+
+/**
+ * Test reading sound data from a ppt
+ *
+ * @author Yegor Kozlov
+ */
+public class TestSoundData extends TestCase{
+
+ protected File cwd;
+
+ public void setUp() throws Exception {
+ cwd = new File(System.getProperty("HSLF.testdata.path"));
+ }
+
+ /**
+ * Read a reference sound file from disk and compare it from the data extracted from the slide show
+ */
+ public void testSounds() throws Exception {
+ //read the reference sound file
+ File f = new File(cwd, "ringin.wav");
+ int length = (int)f.length();
+ byte[] ref_data = new byte[length];
+ FileInputStream is = new FileInputStream(f);
+ is.read(ref_data);
+ is.close();
+
+ is = new FileInputStream(new File(cwd, "sound.ppt"));
+ SlideShow ppt = new SlideShow(is);
+ is.close();
+
+ SoundData[] sound = ppt.getSoundData();
+ assertEquals("Expected 1 sound", 1, sound.length);
+
+ assertTrue(Arrays.equals(ref_data, sound[0].getData()));
+ }
+}
|