poi-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From n...@apache.org
Subject svn commit: r448001 - in /jakarta/poi/trunk/src: documentation/content/xdocs/hslf/ scratchpad/src/org/apache/poi/hslf/ scratchpad/src/org/apache/poi/hslf/blip/ scratchpad/src/org/apache/poi/hslf/extractor/ scratchpad/src/org/apache/poi/hslf/model/ scra...
Date Tue, 19 Sep 2006 22:37:39 GMT
Author: nick
Date: Tue Sep 19 15:37:38 2006
New Revision: 448001

URL: http://svn.apache.org/viewvc?view=rev&rev=448001
Log:
Improved picture support for HSLF, from Yegor in bug 40388

Added:
    jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/blip/
    jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/blip/Bitmap.java
    jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/blip/EMF.java
    jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/blip/JPEG.java
    jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/blip/Metafile.java
    jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/blip/PICT.java
    jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/blip/PNG.java
    jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/blip/WMF.java
    jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/extractor/ImageExtractor.java
    jakarta/poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/data/cow.pict   (with props)
    jakarta/poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/data/pictures.ppt   (with props)
    jakarta/poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/data/santa.wmf   (with props)
    jakarta/poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/data/tomcat.png   (with props)
    jakarta/poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/data/wrench.emf   (with props)
Modified:
    jakarta/poi/trunk/src/documentation/content/xdocs/hslf/how-to-shapes.xml
    jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/HSLFSlideShow.java
    jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Picture.java
    jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/PictureData.java
    jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/SlideShow.java
    jakarta/poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestPictures.java

Modified: jakarta/poi/trunk/src/documentation/content/xdocs/hslf/how-to-shapes.xml
URL: http://svn.apache.org/viewvc/jakarta/poi/trunk/src/documentation/content/xdocs/hslf/how-to-shapes.xml?view=diff&rev=448001&r1=448000&r2=448001
==============================================================================
--- jakarta/poi/trunk/src/documentation/content/xdocs/hslf/how-to-shapes.xml (original)
+++ jakarta/poi/trunk/src/documentation/content/xdocs/hslf/how-to-shapes.xml Tue Sep 19 15:37:38 2006
@@ -17,7 +17,7 @@
                     <li><link href="#PageSize">How to retrieve or change slide size</link></li>
                     <li><link href="#GetShapes">How to get shapes contained in a particular slide</link></li>
                     <li><link href="#Shapes">Drawing a shape on a slide</link></li>
-                    <li><link href="#Pictures">How to add/retrieve pictures</link></li>
+                    <li><link href="#Pictures">How to work with pictures</link></li>
                     <li><link href="#SlideTitle">How to set slide title</link></li>
                 </ul>
             </section>
@@ -106,7 +106,7 @@
                      corner of the slide. Distances in the drawing layer are measured in points (72 points = 1 inch).
                    </p>
                     <source>
-  SlideShow ppt = new SlideShow);
+        SlideShow ppt = new SlideShow();
 
   Slide slide = ppt.createSlide();
 
@@ -120,10 +120,18 @@
   //TextBox
   TextBox txt = new TextBox();
   txt.setText("Hello, World!");
-  txt.setAnchor(new java.awt.Rectangle(100, 100, 200, 50));
-  txt.setFontSize(32);
-  txt.setFontName("Arial");
-  txt.setBold(true);
+        txt.setAnchor(new java.awt.Rectangle(300, 100, 300, 50));
+
+        //use RichTextRun to work with the text format
+        RichTextRun rt = txt.getRichTextRuns()[0];
+        rt.setFontSize(32);
+        rt.setFontName("Arial");
+        rt.setBold(true);
+        rt.setItalic(true);
+        rt.setUnderlined(true);
+        rt.setFontColor(Color.red);
+        rt.setAlignment(TextBox.AlignRight);
+
   slide.addShape(txt);
 
   //Autoshape
@@ -140,15 +148,24 @@
   slide.addShape(sh2);
 
   FileOutputStream out = new FileOutputStream("slideshow.ppt");
-  wb.write(out);
+        ppt.write(out);
   out.close();
                   </source>
                 </section>
                 <anchor id="Pictures"/>
-                <section><title>How to add/retrieve pictures</title>
-                  <p>
-                    Note, for now only PNG and JPEG formats are supported.
-                  </p>
+                <section><title>How to work with pictures</title>
+                 
+  <p>
+  Currently, HSLF API supports the following types of pictures:
+  <ul>
+    <li>Windows Metafiles (WMF)</li>
+    <li>Enhanced Metafiles (EMF)</li>
+    <li>JPEG Interchange Format</li>
+    <li>Portable Network Graphics (PNG)</li>
+    <li>Macintosh PICT</li>
+  </ul>
+  </p>
+
                     <source>
   SlideShow ppt = new SlideShow(new HSLFSlideShow("slideshow.ppt"));
 
@@ -157,19 +174,23 @@
   for (int i = 0; i &lt; pdata.length; i++){
     PictureData pict = pdata[i];
 
-    //raw picture data
+    // picture data
     byte[] data = pict.getData();
 
     int type = pict.getType();
-    if (type == Picture.JPEG){
-      FileOutputStream out = new FileOutputStream("pict"+i+".jpg");
-      out.write(data);
-      out.close();
-    } else if (type == Picture.PNG){
-      FileOutputStream out = new FileOutputStream("pict"+i+".png");
+    String ext;
+    switch (type){
+      case Picture.JPEG: ext=".jpg"; break;
+      case Picture.PNG: ext=".png"; break;
+      case Picture.WMF: ext=".wmf"; break;
+      case Picture.EMF: ext=".emf"; break;
+      case Picture.PICT: ext=".pict"; break;
+      default: continue;
+    }
+    FileOutputStream out = new FileOutputStream("pict_"+i + ext);
       out.write(data);
       out.close();
-    }
+
   }
 
   // add a new picture to this slideshow and insert it in a  new slide

Modified: jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/HSLFSlideShow.java
URL: http://svn.apache.org/viewvc/jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/HSLFSlideShow.java?view=diff&rev=448001&r1=448000&r2=448001
==============================================================================
--- jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/HSLFSlideShow.java (original)
+++ jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/HSLFSlideShow.java Tue Sep 19 15:37:38 2006
@@ -23,6 +23,7 @@
 import java.io.*;
 
 import org.apache.poi.POIDocument;
+import org.apache.poi.util.LittleEndian;
 import org.apache.poi.poifs.filesystem.POIFSFileSystem;
 import org.apache.poi.poifs.filesystem.DocumentEntry;
 import org.apache.poi.poifs.filesystem.DocumentInputStream;
@@ -251,13 +252,31 @@
 			return;
 		}
 
-		ArrayList p = new ArrayList();
-		int pos = 0; 
-		while (pos < (pictstream.length - PictureData.HEADER_SIZE)) {
-			PictureData pict = new PictureData(pictstream, pos);
-			p.add(pict);
-			pos += PictureData.HEADER_SIZE + pict.getSize();
-		}
+        List p = new ArrayList();
+        int pos = 0;
+
+        while (pos < pictstream.length) {
+            int offset = pos;
+
+            //image signature
+            int signature = LittleEndian.getUShort(pictstream, pos);
+            pos += LittleEndian.SHORT_SIZE;
+            //image type + 0xF018
+            int type = LittleEndian.getUShort(pictstream, pos);
+            pos += LittleEndian.SHORT_SIZE;
+            //image size
+            int imgsize = LittleEndian.getInt(pictstream, pos);
+            pos += LittleEndian.INT_SIZE;
+
+            byte[] imgdata = new byte[imgsize];
+            System.arraycopy(pictstream, pos, imgdata, 0, imgdata.length);
+
+            PictureData pict = PictureData.create(type - 0xF018);
+            pict.setRawData(imgdata);
+            pict.setOffset(offset);
+            p.add(pict);
+            pos += imgsize;
+        }
 
 		_pictures = (PictureData[])p.toArray(new PictureData[p.size()]);
 	}

Added: jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/blip/Bitmap.java
URL: http://svn.apache.org/viewvc/jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/blip/Bitmap.java?view=auto&rev=448001
==============================================================================
--- jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/blip/Bitmap.java (added)
+++ jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/blip/Bitmap.java Tue Sep 19 15:37:38 2006
@@ -0,0 +1,47 @@
+/* ====================================================================
+   Copyright 2002-2004   Apache Software Foundation
+
+   Licensed 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.blip;
+
+import org.apache.poi.hslf.usermodel.PictureData;
+
+import java.io.IOException;
+import java.io.ByteArrayOutputStream;
+
+/**
+ * Represents a bitmap picture data:  JPEG or PNG.
+ * The data is not compressed and the exact file content is written in the stream.
+ * 
+ * @author Yegor Kozlov
+ */
+public abstract  class Bitmap extends PictureData {
+
+    public byte[] getData(){
+        byte[] rawdata = getRawData();
+        byte[] imgdata = new byte[rawdata.length-17];
+        System.arraycopy(rawdata, 17, imgdata, 0, imgdata.length);
+        return imgdata;
+    }
+
+    public void setData(byte[] data) throws IOException {
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        byte[] checksum = getChecksum(data);
+        out.write(checksum);
+        out.write(0);
+        out.write(data);
+
+        setRawData(out.toByteArray());
+    }
+}

Added: jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/blip/EMF.java
URL: http://svn.apache.org/viewvc/jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/blip/EMF.java?view=auto&rev=448001
==============================================================================
--- jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/blip/EMF.java (added)
+++ jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/blip/EMF.java Tue Sep 19 15:37:38 2006
@@ -0,0 +1,92 @@
+/* ====================================================================
+   Copyright 2002-2004   Apache Software Foundation
+
+   Licensed 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.blip;
+
+import org.apache.poi.hslf.model.Picture;
+import org.apache.poi.hslf.model.Shape;
+
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.util.zip.InflaterInputStream;
+import java.util.zip.DeflaterOutputStream;
+
+/**
+ * Represents EMF (Windows Enhanced Metafile) picture data.
+ * 
+ * @author Yegor Kozlov
+ */
+public class EMF extends Metafile {
+
+    /**
+     * Extract compressed EMF data from a ppt
+     */
+    public byte[] getData(){
+        try {
+            byte[] rawdata = getRawData();
+
+            ByteArrayOutputStream out = new ByteArrayOutputStream();
+            InputStream is = new ByteArrayInputStream( rawdata );
+            Header header = new Header();
+            header.read(rawdata, CHECKSUM_SIZE);
+            is.skip(header.getSize() + CHECKSUM_SIZE);
+
+            InflaterInputStream inflater = new InflaterInputStream( is );
+            byte[] chunk = new byte[4096];
+            int count;
+            while ((count = inflater.read(chunk)) >=0 ) {
+                out.write(chunk,0,count);
+            }
+            inflater.close();
+            return out.toByteArray();
+        } catch (IOException e){
+            throw new RuntimeException(e);
+        }
+    }
+
+    public void setData(byte[] data) throws IOException {
+        byte[] compressed = compress(data, 0, data.length);
+
+        Header header = new Header();
+        header.wmfsize = data.length;
+        //we don't have a EMF reader in java, have to set default image size  200x200
+        header.bounds = new java.awt.Rectangle(0, 0, 200, 200);
+        header.size = new java.awt.Dimension(header.bounds.width*Shape.EMU_PER_POINT, header.bounds.height*Shape.EMU_PER_POINT);
+        header.zipsize = compressed.length;
+
+        byte[] checksum = getChecksum(data);
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        out.write(checksum);
+        header.write(out);
+        out.write(compressed);
+
+        setRawData(out.toByteArray());
+    }
+
+    public int getType(){
+        return Picture.EMF;
+    }
+
+    /**
+     * EMF signature is <code>0x3D40</code>
+     *
+     * @return EMF signature (<code>0x3D40</code>)
+     */
+    public int getSignature(){
+        return 0x3D40;
+    }
+}

Added: jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/blip/JPEG.java
URL: http://svn.apache.org/viewvc/jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/blip/JPEG.java?view=auto&rev=448001
==============================================================================
--- jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/blip/JPEG.java (added)
+++ jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/blip/JPEG.java Tue Sep 19 15:37:38 2006
@@ -0,0 +1,43 @@
+/* ====================================================================
+   Copyright 2002-2004   Apache Software Foundation
+
+   Licensed 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.blip;
+
+import org.apache.poi.hslf.model.Picture;
+
+/**
+ * Represents a JPEG picture data in a PPT file
+ * 
+ * @author Yegor Kozlov
+ */
+public class JPEG extends Bitmap {
+
+    /**
+     * @return type of  this picture
+     * @see  org.apache.poi.hslf.model.Picture#JPEG
+     */
+    public int getType(){
+        return Picture.JPEG;
+    }
+
+    /**
+     * JPEG signature is <code>0x46A0</code>
+     *
+     * @return JPEG signature (<code>0x46A0</code>)
+     */
+    public int getSignature(){
+        return 0x46A0;
+    }
+}

Added: jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/blip/Metafile.java
URL: http://svn.apache.org/viewvc/jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/blip/Metafile.java?view=auto&rev=448001
==============================================================================
--- jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/blip/Metafile.java (added)
+++ jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/blip/Metafile.java Tue Sep 19 15:37:38 2006
@@ -0,0 +1,123 @@
+/* ====================================================================
+   Copyright 2002-2004   Apache Software Foundation
+
+   Licensed 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.blip;
+
+import org.apache.poi.util.LittleEndian;
+import org.apache.poi.hslf.usermodel.PictureData;
+
+import java.awt.*;
+import java.io.*;
+import java.util.zip.DeflaterOutputStream;
+import java.util.zip.InflaterInputStream;
+
+/**
+ * Represents a metafile picture which can be one of the following types: EMF, WMF, or PICT.
+ * A metafile is stored compressed using the ZIP deflate/inflate algorithm.
+ * 
+ * @author Yegor Kozlov
+ */
+public abstract class Metafile extends PictureData {
+
+    /**
+     *  A structure which represents a 34-byte header preceeding the compressed metafile data
+     *
+     * @author Yegor Kozlov
+     */
+    public static class Header{
+
+        /**
+         * size of the original file
+         */
+        public int wmfsize;
+
+        /**
+         * Boundary of the metafile drawing commands
+         */
+        public Rectangle bounds;
+
+        /**
+         *  Size of the metafile in EMUs
+         */
+        public Dimension size;
+
+        /**
+         * size of the compressed metafile data
+         */
+        public int zipsize;
+
+        /**
+         * Reserved. Always 0.
+         */
+        public int compression;
+
+        /**
+         * Reserved. Always 254.
+         */
+        public int filter = 254;
+
+        public void read(byte[] data, int offset){
+            int pos = offset;
+            wmfsize = LittleEndian.getInt(data, pos);   pos += LittleEndian.INT_SIZE;
+
+            int left = LittleEndian.getInt(data, pos); pos += LittleEndian.INT_SIZE;
+            int top = LittleEndian.getInt(data, pos); pos += LittleEndian.INT_SIZE;
+            int right = LittleEndian.getInt(data, pos); pos += LittleEndian.INT_SIZE;
+            int bottom = LittleEndian.getInt(data, pos); pos += LittleEndian.INT_SIZE;
+
+            bounds = new Rectangle(left, top, right-left, bottom-top);
+            int width = LittleEndian.getInt(data, pos); pos += LittleEndian.INT_SIZE;
+            int height = LittleEndian.getInt(data, pos); pos += LittleEndian.INT_SIZE;
+
+            size = new Dimension(width, height);
+
+            zipsize = LittleEndian.getInt(data, pos); pos += LittleEndian.INT_SIZE;
+
+            compression = LittleEndian.getUnsignedByte(data, pos); pos++;
+            filter = LittleEndian.getUnsignedByte(data, pos); pos++;
+        }
+
+        public void write(OutputStream out) throws IOException {
+            byte[] header = new byte[34];
+            int pos = 0;
+            LittleEndian.putInt(header, pos, wmfsize); pos += LittleEndian.INT_SIZE; //hmf
+
+            LittleEndian.putInt(header, pos, bounds.x); pos += LittleEndian.INT_SIZE; //left
+            LittleEndian.putInt(header, pos, bounds.y); pos += LittleEndian.INT_SIZE; //top
+            LittleEndian.putInt(header, pos, bounds.x + bounds.width); pos += LittleEndian.INT_SIZE; //right
+            LittleEndian.putInt(header, pos, bounds.y + bounds.height); pos += LittleEndian.INT_SIZE; //bottom
+            LittleEndian.putInt(header, pos, size.width); pos += LittleEndian.INT_SIZE; //inch
+            LittleEndian.putInt(header, pos, size.height); pos += LittleEndian.INT_SIZE; //inch
+            LittleEndian.putInt(header, pos, zipsize); pos += LittleEndian.INT_SIZE; //inch
+
+            header[pos] = 0; pos ++;
+            header[pos] = (byte)filter; pos ++;
+
+            out.write(header);
+        }
+
+        public int getSize(){
+            return 34;
+        }
+    }
+
+    protected byte[] compress(byte[] bytes, int offset, int length) throws IOException {
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        DeflaterOutputStream  deflater = new DeflaterOutputStream( out );
+        deflater.write(bytes, offset, length);
+        deflater.close();
+        return out.toByteArray();
+    }
+}

Added: jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/blip/PICT.java
URL: http://svn.apache.org/viewvc/jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/blip/PICT.java?view=auto&rev=448001
==============================================================================
--- jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/blip/PICT.java (added)
+++ jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/blip/PICT.java Tue Sep 19 15:37:38 2006
@@ -0,0 +1,117 @@
+/* ====================================================================
+   Copyright 2002-2004   Apache Software Foundation
+
+   Licensed 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.blip;
+
+import org.apache.poi.hslf.model.Picture;
+import org.apache.poi.hslf.model.Shape;
+import org.apache.poi.util.LittleEndian;
+
+import java.io.*;
+import java.util.zip.InflaterInputStream;
+import java.util.zip.DeflaterOutputStream;
+
+/**
+ * Represents Macintosh PICT picture data.
+ * 
+ * @author Yegor Kozlov
+ */
+public class PICT extends Metafile {
+
+    public PICT(){
+        super();
+    }
+
+    /**
+     * Extract compressed PICT data from a ppt
+     */
+    public byte[] getData(){
+        byte[] rawdata = getRawData();
+        try {
+            byte[] macheader = new byte[512];
+            ByteArrayOutputStream out = new ByteArrayOutputStream();
+            out.write(macheader);
+            int pos = CHECKSUM_SIZE;
+            byte[] pict;
+            try {
+                pict = read(rawdata, pos);
+            } catch (IOException e){
+                //weird MAC behaviour.
+                //if failed to read right after the checksum - skip 16 bytes and try again
+                pict = read(rawdata, pos + 16);
+            }
+            out.write(pict);
+            return out.toByteArray();
+        } catch (IOException e){
+            throw new RuntimeException(e);
+        }
+    }
+
+    private byte[] read(byte[] data, int pos) throws IOException {
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        ByteArrayInputStream bis = new ByteArrayInputStream(data);
+        Header header = new Header();
+        header.read(data, pos);
+        bis.skip(pos + header.getSize());
+        InflaterInputStream inflater = new InflaterInputStream( bis );
+        byte[] chunk = new byte[4096];
+        int count;
+        while ((count = inflater.read(chunk)) >=0 ) {
+            out.write(chunk,0,count);
+        }
+        inflater.close();
+        return out.toByteArray();
+    }
+
+    public void setData(byte[] data) throws IOException {
+        int pos = 512; //skip the first 512 bytes - they are MAC specific crap
+        byte[] compressed = compress(data, pos, data.length-pos);
+
+        Header header = new Header();
+        header.wmfsize = data.length - 512;
+        //we don't have a PICT reader in java, have to set default image size  200x200
+        header.bounds = new java.awt.Rectangle(0, 0, 200, 200);
+        header.size = new java.awt.Dimension(header.bounds.width*Shape.EMU_PER_POINT,
+                header.bounds.height*Shape.EMU_PER_POINT);
+        header.zipsize = compressed.length;
+
+        byte[] checksum = getChecksum(data);
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        out.write(checksum);
+
+        out.write(new byte[16]); //16-byte prefix which is safe to ignore
+        header.write(out);
+        out.write(compressed);
+
+        setRawData(out.toByteArray());
+    }
+
+    /**
+     * @see org.apache.poi.hslf.model.Picture#PICT
+     */
+    public int getType(){
+        return Picture.PICT;
+    }
+
+    /**
+     * PICT signature is <code>0x5430</code>
+     *
+     * @return PICT signature (<code>0x5430</code>)
+     */
+    public int getSignature(){
+        return 0x5430;
+    }
+
+}

Added: jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/blip/PNG.java
URL: http://svn.apache.org/viewvc/jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/blip/PNG.java?view=auto&rev=448001
==============================================================================
--- jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/blip/PNG.java (added)
+++ jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/blip/PNG.java Tue Sep 19 15:37:38 2006
@@ -0,0 +1,68 @@
+/* ====================================================================
+   Copyright 2002-2004   Apache Software Foundation
+
+   Licensed 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.blip;
+
+import org.apache.poi.hslf.model.Picture;
+
+import javax.imageio.ImageIO;
+import java.awt.image.BufferedImage;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+
+/**
+ * Represents a PNG picture data in a PPT file
+ * 
+ * @author Yegor Kozlov
+ */
+public class PNG extends Bitmap {
+
+    /**
+     * @return PNG data
+     */
+    public byte[] getData(){
+         byte[] data = super.getData();
+          try {
+              //PNG created on MAC may have a 16-byte prefix which prevents successful reading.
+              //Just cut it off!.
+              BufferedImage bi = ImageIO.read(new ByteArrayInputStream(data));
+              if (bi == null){
+                  byte[] png = new byte[data.length-16];
+                  System.arraycopy(data, 16, png, 0, png.length);
+                  data = png;
+              }
+          } catch (IOException e){
+              throw new RuntimeException(e);
+          }
+         return data;
+     }
+
+    /**
+     * @return type of  this picture
+     * @see  org.apache.poi.hslf.model.Picture#PNG
+     */
+    public int getType(){
+        return Picture.PNG;
+    }
+
+    /**
+     * PNG signature is <code>0x6E00</code>
+     *
+     * @return PNG signature (<code>0x6E00</code>)
+     */
+    public int getSignature(){
+        return 0x6E00;
+    }
+}

Added: jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/blip/WMF.java
URL: http://svn.apache.org/viewvc/jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/blip/WMF.java?view=auto&rev=448001
==============================================================================
--- jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/blip/WMF.java (added)
+++ jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/blip/WMF.java Tue Sep 19 15:37:38 2006
@@ -0,0 +1,187 @@
+/* ====================================================================
+   Copyright 2002-2004   Apache Software Foundation
+
+   Licensed 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.blip;
+
+import org.apache.poi.util.LittleEndian;
+import org.apache.poi.hslf.model.Picture;
+import org.apache.poi.hslf.model.Shape;
+
+import java.io.*;
+import java.util.zip.InflaterInputStream;
+import java.util.zip.DeflaterOutputStream;
+
+/**
+ * Represents a WMF (Windows Metafile) picture data.
+ * 
+ * @author Yegor Kozlov
+ */
+public class WMF extends Metafile {
+
+    /**
+     * Extract compressed WMF data from a ppt
+     */
+    public byte[] getData(){
+        try {
+            byte[] rawdata = getRawData();
+
+            ByteArrayOutputStream out = new ByteArrayOutputStream();
+            InputStream is = new ByteArrayInputStream( rawdata );
+            Header header = new Header();
+            header.read(rawdata, CHECKSUM_SIZE);
+            is.skip(header.getSize() + CHECKSUM_SIZE);
+
+            AldusHeader aldus = new AldusHeader();
+            aldus.left = header.bounds.x;
+            aldus.top = header.bounds.y;
+            aldus.right = header.bounds.x + header.bounds.width;
+            aldus.bottom = header.bounds.y + header.bounds.height;
+            aldus.write(out);
+
+            InflaterInputStream inflater = new InflaterInputStream( is );
+            byte[] chunk = new byte[4096];
+            int count;
+            while ((count = inflater.read(chunk)) >=0 ) {
+                out.write(chunk,0,count);
+            }
+            inflater.close();
+            return out.toByteArray();
+        } catch (IOException e){
+            throw new RuntimeException(e);
+        }
+    }
+
+    public void setData(byte[] data) throws IOException {
+        int pos = 0;
+        AldusHeader aldus = new AldusHeader();
+        aldus.read(data, pos);
+        pos += aldus.getSize();
+
+        byte[] compressed = compress(data, pos, data.length-pos);
+
+        Header header = new Header();
+        header.wmfsize = data.length - aldus.getSize();
+        header.bounds = new java.awt.Rectangle((short)aldus.left, (short)aldus.top, (short)aldus.right-(short)aldus.left, (short)aldus.bottom-(short)aldus.top);
+        //coefficiaent to translate from WMF dpi to 96pdi
+        int coeff = 96*Shape.EMU_PER_POINT/aldus.inch;
+        header.size = new java.awt.Dimension(header.bounds.width*coeff, header.bounds.height*coeff);
+        header.zipsize = compressed.length;
+
+        byte[] checksum = getChecksum(data);
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        out.write(checksum);
+        header.write(out);
+        out.write(compressed);
+
+        setRawData(out.toByteArray());
+    }
+
+    /**
+     * We are of type <code>Picture.WMF</code>
+     */
+    public int getType(){
+        return Picture.WMF;
+    }
+
+    /**
+     * WMF signature is <code>0x2160</code>
+     */
+    public int getSignature(){
+        return 0x2160;
+    }
+
+
+    /**
+     * Aldus Placeable Metafile header - 22 byte structure before WMF data.
+     * <ul>
+     *  <li>int Key;               Magic number (always 9AC6CDD7h)
+     *  <li>short  Handle;         Metafile HANDLE number (always 0)
+     *  <li>short Left;            Left coordinate in metafile units
+     *  <li>short Top;             Top coordinate in metafile units
+     *  <li>short Right;           Right coordinate in metafile units
+     *  <li>short Bottom;          Bottom coordinate in metafile units
+     *  <li>short  Inch;           Number of metafile units per inch
+     *  <li>int Reserved;          Reserved (always 0)
+     *  <li>short  Checksum;       Checksum value for previous 10 shorts
+     * </ul>
+     */
+    public static class AldusHeader{
+        public static final int APMHEADER_KEY = 0x9AC6CDD7;
+
+        public int handle;
+        public int left, top, right, bottom;
+        public int inch = 72; //default resolution is 72 dpi
+        public int reserved;
+        public int checksum;
+
+        public void read(byte[] data, int offset){
+            int pos = offset;
+            int key = LittleEndian.getInt(data, pos); pos += LittleEndian.INT_SIZE; //header key
+            if (key != APMHEADER_KEY) throw new RuntimeException("Not a valid WMF file");
+
+            handle = LittleEndian.getUShort(data, pos); pos += LittleEndian.SHORT_SIZE;
+            left = LittleEndian.getUShort(data, pos); pos += LittleEndian.SHORT_SIZE;
+            top = LittleEndian.getUShort(data, pos); pos += LittleEndian.SHORT_SIZE;
+            right = LittleEndian.getUShort(data, pos); pos += LittleEndian.SHORT_SIZE;
+            bottom = LittleEndian.getUShort(data, pos); pos += LittleEndian.SHORT_SIZE;
+
+            inch = LittleEndian.getUShort(data, pos); pos += LittleEndian.SHORT_SIZE;
+            reserved = LittleEndian.getInt(data, pos); pos += LittleEndian.INT_SIZE;
+
+            checksum = LittleEndian.getShort(data, pos); pos += LittleEndian.SHORT_SIZE;
+            if (checksum != getChecksum())
+                throw new RuntimeException("WMF checksum does not match the header data");
+        }
+
+        /**
+         * Returns a checksum value for the previous 10 shorts in the header.
+         * The checksum is calculated by XORing each short value to an initial value of 0:
+         */
+        public int getChecksum(){
+            int checksum = 0;
+            checksum ^=  (APMHEADER_KEY & 0x0000FFFF);
+            checksum ^= ((APMHEADER_KEY & 0xFFFF0000) >> 16);
+            checksum ^= left;
+            checksum ^= top;
+            checksum ^= right;
+            checksum ^= bottom;
+            checksum ^= inch;
+            return checksum;
+        }
+
+        public void write(OutputStream out) throws IOException {
+            byte[] header = new byte[22];
+            int pos = 0;
+            LittleEndian.putInt(header, pos, APMHEADER_KEY); pos += LittleEndian.INT_SIZE; //header key
+            LittleEndian.putUShort(header, pos, 0); pos += LittleEndian.SHORT_SIZE; //hmf
+            LittleEndian.putUShort(header, pos, left); pos += LittleEndian.SHORT_SIZE; //left
+            LittleEndian.putUShort(header, pos, top); pos += LittleEndian.SHORT_SIZE; //top
+            LittleEndian.putUShort(header, pos, right); pos += LittleEndian.SHORT_SIZE; //right
+            LittleEndian.putUShort(header, pos, bottom); pos += LittleEndian.SHORT_SIZE; //bottom
+            LittleEndian.putUShort(header, pos, inch); pos += LittleEndian.SHORT_SIZE; //inch
+            LittleEndian.putInt(header, pos, 0); pos += LittleEndian.INT_SIZE;  //reserved
+
+            checksum = getChecksum();
+            LittleEndian.putUShort(header, pos, checksum);
+
+            out.write(header);
+        }
+
+        public int getSize(){
+            return 22;
+        }
+    }
+
+}

Added: jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/extractor/ImageExtractor.java
URL: http://svn.apache.org/viewvc/jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/extractor/ImageExtractor.java?view=auto&rev=448001
==============================================================================
--- jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/extractor/ImageExtractor.java (added)
+++ jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/extractor/ImageExtractor.java Tue Sep 19 15:37:38 2006
@@ -0,0 +1,75 @@
+
+/* ====================================================================
+   Copyright 2002-2004   Apache Software Foundation
+
+   Licensed 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.extractor;
+
+import org.apache.poi.hslf.usermodel.SlideShow;
+import org.apache.poi.hslf.usermodel.PictureData;
+import org.apache.poi.hslf.HSLFSlideShow;
+import org.apache.poi.hslf.model.Picture;
+
+import java.io.IOException;
+import java.io.FileOutputStream;
+
+/**
+ * Utility to extract pictures from a PowerPoint file.
+ *
+ * @author Yegor Kozlov
+ */
+public class ImageExtractor {
+    public static void main(String args[]) throws IOException {
+        if (args.length < 1) {
+            System.err.println("Usage:");
+            System.err.println("\tImageExtractor <file>");
+            return;
+        }
+        SlideShow ppt = new SlideShow(new HSLFSlideShow(args[0]));
+
+        //extract all pictures contained in the presentation
+        PictureData[] pdata = ppt.getPictureData();
+        for (int i = 0; i < pdata.length; i++) {
+            PictureData pict = pdata[i];
+
+            // picture data
+            byte[] data = pict.getData();
+
+            int type = pict.getType();
+            String ext;
+            switch (type) {
+                case Picture.JPEG:
+                    ext = ".jpg";
+                    break;
+                case Picture.PNG:
+                    ext = ".png";
+                    break;
+                case Picture.WMF:
+                    ext = ".wmf";
+                    break;
+                case Picture.EMF:
+                    ext = ".emf";
+                    break;
+                case Picture.PICT:
+                    ext = ".pict";
+                    break;
+                default:
+                    continue;
+            }
+            FileOutputStream out = new FileOutputStream("pict_" + i + ext);
+            out.write(data);
+            out.close();
+        }
+    }
+}

Modified: jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Picture.java
URL: http://svn.apache.org/viewvc/jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Picture.java?view=diff&rev=448001&r1=448000&r2=448001
==============================================================================
--- jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Picture.java (original)
+++ jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Picture.java Tue Sep 19 15:37:38 2006
@@ -4,9 +4,11 @@
 import org.apache.poi.hslf.usermodel.PictureData;
 import org.apache.poi.hslf.usermodel.SlideShow;
 import org.apache.poi.hslf.record.Document;
+import org.apache.poi.hslf.blip.Bitmap;
 
 import javax.imageio.ImageIO;
 import java.awt.image.BufferedImage;
+import java.awt.*;
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.util.List;
@@ -22,33 +24,23 @@
  *    type, image index to refer by slides etc.
  *  <li> "Pictures" OLE stream holds the actual data of the image.
  * </p>
- * <p>
- *  Data in the "Pictures" OLE stream is organized as follows:<br>
- *  For each image there is an entry: 25 byte header + image data.
- *  Image data is the exact content of the JPEG file, i.e. PowerPoint
- *  puts the whole jpeg file there without any modifications.<br>
- *   Header format:
- *    <li> 2 byte: image type. For JPEGs it is 0x46A0, for PNG it is 0x6E00.
- *    <li> 2 byte: unknown.
- *    <li> 4 byte : image size + 17. Looks like shift from the end of
- *          header but why to add it to the image  size?
- *    <li> next 16 bytes. Unique identifier of this image which is used by
- *          EscherBSE record.
- *  </p>
  *
  * @author Yegor Kozlov
  */
 public class Picture extends SimpleShape {
 
     /**
-    *  Windows Metafile
-    *  ( NOT YET SUPPORTED )
+    *  Windows Enhanced Metafile (EMF)
+    */
+    public static final int EMF = 2;
+
+    /**
+    *  Windows Metafile (WMF)
     */
     public static final int WMF = 3;
 
     /**
     * Macintosh PICT
-     *  ( NOT YET SUPPORTED )
     */
     public static final int PICT = 4;
 
@@ -63,10 +55,10 @@
     public static final int PNG = 6;
 
     /**
-    * Windows DIB (BMP)
-    */
-    public static final int DIB = 7;
-
+     * Windows DIB (BMP)
+     */
+    public static final byte DIB = 7;
+    
     /**
      * Create a new <code>Picture</code>
      *
@@ -129,11 +121,17 @@
      */
     public void setDefaultSize(){
         PictureData pict = getPictureData();
-        try {
-            BufferedImage img = ImageIO.read(new ByteArrayInputStream(pict.getData()));
-            setAnchor(new java.awt.Rectangle(0, 0, img.getWidth(), img.getHeight()));
-        } catch (IOException e){
-            throw new RuntimeException(e);
+        if (pict  instanceof Bitmap){
+            try {
+                BufferedImage img = ImageIO.read(new ByteArrayInputStream(pict.getData()));
+                if(img != null) setAnchor(new java.awt.Rectangle(0, 0, img.getWidth(), img.getHeight()));
+                else setAnchor(new java.awt.Rectangle(0, 0, 200, 200));
+            } catch (IOException e){
+                ;
+            }
+        } else {
+            //default size of a metafile picture is 200x200 
+            setAnchor(new java.awt.Rectangle(50, 50, 200, 200));
         }
     }
 

Modified: jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/PictureData.java
URL: http://svn.apache.org/viewvc/jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/PictureData.java?view=diff&rev=448001&r1=448000&r2=448001
==============================================================================
--- jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/PictureData.java (original)
+++ jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/PictureData.java Tue Sep 19 15:37:38 2006
@@ -17,6 +17,7 @@
 
 import org.apache.poi.util.LittleEndian;
 import org.apache.poi.hslf.model.Picture;
+import org.apache.poi.hslf.blip.*;
 
 import java.io.OutputStream;
 import java.io.IOException;
@@ -24,172 +25,95 @@
 import java.security.NoSuchAlgorithmException;
 
 /**
- * A class that represents the image data contained in the Presentation.
- * 
+ * A class that represents image data contained in a slide show.
  *
  *  @author Yegor Kozlov
  */
-public class PictureData {
+public abstract class PictureData {
 
-	/**
-	* The size of the header
-	*/
-	public static final int HEADER_SIZE = 25;
-
-    protected static final int JPEG_HEADER = -266516832;
-    protected static final int PNG_HEADER = -266441216;
+    /**
+     * Size of the image checksum calculated using MD5 algorithm.
+     */
+    protected static final int CHECKSUM_SIZE = 16;
 
 	/**
 	* Binary data of the picture
 	*/
-	protected byte[] pictdata;
-
-	/**
-	* Header which holds information about this picture
-	*/
-	protected byte[] header;
-
+    private byte[] rawdata;
 	/**
 	 * The offset to the picture in the stream
 	 */
 	protected int offset;
 
-    public PictureData(){
-        header = new byte[PictureData.HEADER_SIZE];
-    }
-
-	/**
-	* Read a picture from "Pictures" OLE stream
-	*
-	* @param pictstream    the bytes to read
-	* @param offset        the index of the first byte to read
-	*/
-	public PictureData(byte[] pictstream, int offset){
-		header = new byte[PictureData.HEADER_SIZE];
-		System.arraycopy(pictstream, offset, header, 0, header.length);
-
-		// Get the size of the picture, and make sure it's sane
-		// Size is stored unsigned, since it must always be positive
-		int size = (int)LittleEndian.getUInt(header, 4) - 17;
-		int startPos = offset + PictureData.HEADER_SIZE;
-		if(size < 0) { size = 0; }
-		if(size > (pictstream.length - startPos)) { 
-			int remaining = pictstream.length - startPos;
-			System.err.println("Warning: PictureData claimed picture was of length " + size + ", but only " + remaining + " remained!");
-			size = remaining;
-		}
-
-		// Save the picture data
-		pictdata = new byte[size];
-		this.offset = offset;
-		System.arraycopy(pictstream, startPos, pictdata, 0, pictdata.length);
-	}
+    /**
+     * Returns type of this picture.
+     * Must be one of the static constants defined in the <code>Picture<code> class.
+     *
+     * @return type of this picture.
+     */
+    public abstract int getType();
 
-	/**
-	* @return  the binary data of this picture
-	*/
-	public byte[] getData(){
-		return pictdata;
-	}
+    /**
+     * Returns the binary data of this Picture
+     * @return picture data
+     */
+    public abstract byte[] getData();
 
     /**
      *  Set picture data
      */
-    public void setData(byte[] data) {
-        pictdata = data;
-        LittleEndian.putInt(header, 4, data.length + 17);
-    }
-
-	/**
-	* Return image size in bytes
-	*
-	* @return the size of the picture in bytes
-	*/
-	public int getSize(){
-		return pictdata.length;
-	}
+    public abstract void setData(byte[] data) throws IOException;
 
-	/**
-	* Returns the unique identifier (UID) of this picture.
-	* The UID is a checksum of the picture data. Its length is 16 bytes
-	* and it must be unique across the presentation.
-	*
-	* @return the unique identifier of this picture
-	*/
-	public byte[] getUID(){
-		byte[] uid = new byte[16];
-		System.arraycopy(header, 8, uid, 0, uid.length);
-		return uid;
-	}
+    /**
+     * Blip signature.
+     */
+    protected abstract int getSignature();
 
     /**
-     * Set the unique identifier (UID) of this picture.
+     * Returns the raw binary data of this Picture excluding the first 8 bytes
+     * which hold image signature and size of the image data.
      *
-     * @param uid checksum of the picture data
+     * @return picture data
      */
-    public void setUID(byte[] uid){
-        System.arraycopy(uid, 0, header, 8, uid.length);
+    public byte[] getRawData(){
+        return rawdata;
     }
 
-	/**
-	* Set the type of this picture.
-	*
-	* @return type of this picture.
-    * Must be one of the static constans defined in the <code>Picture<code> class.
-	*/
-	public void setType(int format){
-        switch (format){
-            case Picture.JPEG: LittleEndian.putInt(header, 0, PictureData.JPEG_HEADER); break;
-            case Picture.PNG: LittleEndian.putInt(header, 0, PictureData.PNG_HEADER); break;
-        }
-	}
+    public void setRawData(byte[] data){
+        rawdata = data;
+    }
 
     /**
-     * Returns type of this picture.
-     * Must be one of the static constans defined in the <code>Picture<code> class.
+     * File offset in the 'Pictures' stream
      *
-     * @return type of this picture.
+     * @return offset in the 'Pictures' stream
      */
-    public int getType(){
-        int format = 0;
-        int val = LittleEndian.getInt(header, 0);
-        switch (val){
-            case PictureData.JPEG_HEADER: format = Picture.JPEG; break;
-            case PictureData.PNG_HEADER: format = Picture.PNG; break;
-        }
-        return format;
+    public int getOffset(){
+        return offset;
     }
 
     /**
-     * Returns the header of the Picture
+     * Set offset of this picture in the 'Pictures' stream.
+     * We need to set it when a new picture is created.
      *
-     * @return the header of the Picture
+     * @param offset in the 'Pictures' stream
      */
-    public byte[] getHeader(){
-        return header;
+    public void setOffset(int offset){
+        this.offset = offset;
     }
 
-	/**
-	 * File offset in the 'Pictures' stream
-	 *
-	 * @return offset in the 'Pictures' stream
-	 */
-	public int getOffset(){
-		return offset;
-	}
+    /**
+     * Returns 16-byte checksum of this picture
+     */
+    public byte[] getUID(){
+        byte[] uid = new byte[16];
+        System.arraycopy(rawdata, 0, uid, 0, uid.length);
+        return uid;
+    }
 
-	/**
-	 * Set offset of this picture in the 'Pictures' stream.
-	 * We need to set it when a new picture is created.
-	 *
-	 * @param offset in the 'Pictures' stream
-	 */
-	public void setOffset(int offset){
-		this.offset = offset;
-	}
 
     /**
-     * Compute 16-byte checksum of this picture
+     * Compute 16-byte checksum of this picture using MD5 algorithm.
      */
     public static byte[] getChecksum(byte[] data) {
         MessageDigest sha;
@@ -206,8 +130,81 @@
      * Write this picture into <code>OutputStream</code>
      */
     public void write(OutputStream out) throws IOException {
-        out.write(header);
-        out.write(pictdata);
+        byte[] data;
+
+        data = new byte[LittleEndian.SHORT_SIZE];
+        LittleEndian.putUShort(data, 0, getSignature());
+        out.write(data);
+
+        data = new byte[LittleEndian.SHORT_SIZE];
+        LittleEndian.putUShort(data, 0, getType() + 0xF018);
+        out.write(data);
+
+        byte[] rawdata = getRawData();
+
+        data = new byte[LittleEndian.INT_SIZE];
+        LittleEndian.putInt(data, 0, rawdata.length);
+        out.write(data);
+
+        out.write(rawdata);
+    }
+
+    /**
+     * Create an instance of <code>PictureData</code> by type.
+     *
+     * @param type type of the picture data.
+     * Must be one of the static constants defined in the <code>Picture<code> class.
+     * @return concrete instance of <code>PictureData</code>
+     */
+     public static PictureData create(int type){
+        PictureData pict;
+        switch (type){
+            case Picture.EMF:
+                pict = new EMF();
+                break;
+            case Picture.WMF:
+                pict = new WMF();
+                break;
+            case Picture.PICT:
+                pict = new PICT();
+                break;
+            case Picture.JPEG:
+                pict = new JPEG();
+                break;
+            case Picture.PNG:
+                pict = new PNG();
+                break;
+            default:
+                throw new RuntimeException("Unsupported picture type: " + type);
+        }
+        return pict;
+    }
+
+    /**
+     * Return 24 byte header which preceeds the actual picture data.
+     * <p>
+     * The header consists of 2-byte signature, 2-byte type,
+     * 4-byte image size and 16-byte checksum of the image data.
+     * </p>
+     *
+     * @return the 24 byte header which preceeds the actual picture data.
+     */
+    public byte[] getHeader() {
+        byte[] header = new byte[16 + 8];
+        LittleEndian.putInt(header, 0, getSignature());
+        LittleEndian.putInt(header, 4, getRawData().length);
+        System.arraycopy(rawdata, 0, header, 8, 16);
+        return header;
+    }
+
+    /**
+    * Return image size in bytes
+    *
+    *  @return the size of the picture in bytes
+     * @deprecated Use <code>getData().length</code> instead.
+    */
+    public int getSize(){
+        return getData().length;
     }
 
 }

Modified: jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/SlideShow.java
URL: http://svn.apache.org/viewvc/jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/SlideShow.java?view=diff&rev=448001&r1=448000&r2=448001
==============================================================================
--- jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/SlideShow.java (original)
+++ jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/SlideShow.java Tue Sep 19 15:37:38 2006
@@ -620,7 +620,7 @@
      * @param format    the format of the picture.  One of constans defined in the <code>Picture</code> class.
      * @return          the index to this picture (1 based).
      */
-    public int addPicture(byte[] data, int format) {
+    public int addPicture(byte[] data, int format) throws IOException {
         byte[] uid = PictureData.getChecksum(data);
 
         EscherContainerRecord bstore;
@@ -652,14 +652,23 @@
              }
         }
 
+        PictureData pict = PictureData.create(format);
+        pict.setData(data);
+        pict.setOffset(offset);
+
         EscherBSERecord bse = new EscherBSERecord();
         bse.setRecordId(EscherBSERecord.RECORD_ID);
         bse.setOptions( (short) ( 0x0002 | ( format << 4 ) ) );
-        bse.setSize(data.length + PictureData.HEADER_SIZE);
+        bse.setSize(pict.getRawData().length + 8);
         bse.setUid(uid);
+
         bse.setBlipTypeMacOS((byte)format);
         bse.setBlipTypeWin32((byte)format);
 
+        if (format == Picture.EMF) bse.setBlipTypeMacOS((byte)Picture.PICT);
+        else if (format == Picture.WMF) bse.setBlipTypeMacOS((byte)Picture.PICT);
+        else if (format == Picture.PICT) bse.setBlipTypeWin32((byte)Picture.WMF);
+
         bse.setRef(1);
         bse.setOffset(offset);
 
@@ -667,12 +676,6 @@
         int count = bstore.getChildRecords().size();
         bstore.setOptions((short)( (count << 4) | 0xF ));
 
-        PictureData pict = new PictureData();
-        pict.setUID(uid);
-        pict.setData(data);
-        pict.setType(format);
-		pict.setOffset(offset);
-
         _hslfSlideShow.addPicture(pict);
 
         return count;
@@ -685,7 +688,7 @@
      * @param format    the format of the picture.  One of constans defined in the <code>Picture</code> class.
      * @return          the index to this picture (1 based).
      */
-    public int addPicture(File pict, int format) {
+    public int addPicture(File pict, int format) throws IOException {
         int length = (int)pict.length();
         byte[] data = new byte[length];
         try {

Added: jakarta/poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/data/cow.pict
URL: http://svn.apache.org/viewvc/jakarta/poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/data/cow.pict?view=auto&rev=448001
==============================================================================
Binary file - no diff available.

Propchange: jakarta/poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/data/cow.pict
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: jakarta/poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/data/pictures.ppt
URL: http://svn.apache.org/viewvc/jakarta/poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/data/pictures.ppt?view=auto&rev=448001
==============================================================================
Binary file - no diff available.

Propchange: jakarta/poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/data/pictures.ppt
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: jakarta/poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/data/santa.wmf
URL: http://svn.apache.org/viewvc/jakarta/poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/data/santa.wmf?view=auto&rev=448001
==============================================================================
Binary file - no diff available.

Propchange: jakarta/poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/data/santa.wmf
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: jakarta/poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/data/tomcat.png
URL: http://svn.apache.org/viewvc/jakarta/poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/data/tomcat.png?view=auto&rev=448001
==============================================================================
Binary file - no diff available.

Propchange: jakarta/poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/data/tomcat.png
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: jakarta/poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/data/wrench.emf
URL: http://svn.apache.org/viewvc/jakarta/poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/data/wrench.emf?view=auto&rev=448001
==============================================================================
Binary file - no diff available.

Propchange: jakarta/poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/data/wrench.emf
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Modified: jakarta/poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestPictures.java
URL: http://svn.apache.org/viewvc/jakarta/poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestPictures.java?view=diff&rev=448001&r1=448000&r2=448001
==============================================================================
--- jakarta/poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestPictures.java (original)
+++ jakarta/poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestPictures.java Tue Sep 19 15:37:38 2006
@@ -17,106 +17,316 @@
 package org.apache.poi.hslf.usermodel;
 
 import org.apache.poi.hslf.*;
-import org.apache.poi.hslf.usermodel.PictureData;
-import org.apache.poi.hslf.usermodel.SlideShow;
-import org.apache.poi.hslf.model.Slide;
-import org.apache.poi.hslf.model.Shape;
-import org.apache.poi.hslf.model.Picture;
-import org.apache.poi.util.LittleEndian;
+import org.apache.poi.hslf.blip.*;
+import org.apache.poi.hslf.model.*;
 import junit.framework.TestCase;
 
-import javax.imageio.ImageIO;
-import java.awt.image.BufferedImage;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.File;
+import java.io.*;
+import java.util.Arrays;
 
 /**
- * Test extracting images from a ppt file
+ * Test adding/reading pictures
  *
  * @author Yegor Kozlov
  */
 public class TestPictures extends TestCase{
-    public static String dirname = System.getProperty("HSLF.testdata.path");
-    public static String filename = dirname + "/ppt_with_png.ppt";
 
-    public void testReadPictures() throws Exception {
+    protected File cwd;
+
+    public void setUp() throws Exception {
+        cwd = new File(System.getProperty("HSLF.testdata.path"));
+    }
 
-        HSLFSlideShow ppt = new HSLFSlideShow(filename);
-        PictureData[] pict = ppt.getPictures();
-        assertNotNull(pict);
-        for (int i = 0; i < pict.length; i++) {
-            byte[] data = pict[i].getData();
-
-            BufferedImage img = ImageIO.read(new ByteArrayInputStream(data));
-            assertNotNull(img);
-            assertEquals(Picture.PNG, pict[i].getType());
-        }
-        ppt.close();
-    }
-
-    public void testReadPicturesForSlide() throws Exception {
-
-        SlideShow ppt = new SlideShow(new HSLFSlideShow(filename));
-
-        Slide[] slide = ppt.getSlides();
-        for (int i = 0; i < slide.length; i++) {
-            Slide sl = slide[i];
-            Shape[] sh = sl.getShapes();
-            for (int j = 0; j < sh.length; j++) {
-                Shape shape = sh[j];
-                if (shape instanceof Picture){
-                    Picture picture = (Picture)shape;
-
-                    PictureData pictdata = picture.getPictureData();
-                    assertEquals(Picture.PNG, pictdata.getType());
-
-                    //raw data.
-                    byte[] data = pictdata.getData();
-                    BufferedImage img = ImageIO.read(new ByteArrayInputStream(data));
-                    assertNotNull(img);
-                }
-            }
-
-        }
-    }
-
-    public void testSerializePictures() throws Exception {
-        HSLFSlideShow ppt = new HSLFSlideShow(filename);
-        PictureData[] pict = ppt.getPictures();
-        assertNotNull(pict);
+    /**
+     * Test read/write Macintosh PICT
+     */
+    public void testPICT() throws Exception {
+        SlideShow ppt = new SlideShow();
 
+        Slide slide = ppt.createSlide();
+        File img = new File(cwd, "cow.pict");
+        int idx = ppt.addPicture(img, Picture.PICT);
+        Picture pict = new Picture(idx);
+        assertEquals(idx, pict.getPictureIndex());
+        slide.addShape(pict);
+
+        //serialize and read again
         ByteArrayOutputStream out = new ByteArrayOutputStream();
         ppt.write(out);
         out.close();
 
-        ppt = new HSLFSlideShow(new ByteArrayInputStream(out.toByteArray()));
-        pict = ppt.getPictures();
-        assertNotNull(pict);
+        ppt = new SlideShow(new HSLFSlideShow(new ByteArrayInputStream(out.toByteArray())));
+
+        //make sure we can read this picture shape and it refers to the correct picture data
+        Shape[] sh = ppt.getSlides()[0].getShapes();
+        assertEquals(1, sh.length);
+        pict = (Picture)sh[0];
+        assertEquals(idx, pict.getPictureIndex());
+
+        //check picture data
+        PictureData[] pictures = ppt.getPictureData();
+        //the Picture shape refers to the PictureData object in the Presentation
+        assertEquals(pict.getPictureData(), pictures[0]);
+
+        assertEquals(1, pictures.length);
+        assertEquals(Picture.PICT, pictures[0].getType());
+        assertTrue(pictures[0] instanceof PICT);
+        //compare the content of the initial file with what is stored in the PictureData
+        byte[] src_bytes = read(img);
+        byte[] ppt_bytes = pictures[0].getData();
+        assertEquals(src_bytes.length, ppt_bytes.length);
+        //in PICT the first 512 bytes are MAC specific and may not be preserved, ignore them
+        byte[] b1 = new byte[src_bytes.length-512];
+        System.arraycopy(src_bytes, 512, b1, 0, b1.length);
+        byte[] b2 = new byte[ppt_bytes.length-512];
+        System.arraycopy(ppt_bytes, 512, b2, 0, b2.length);
+        assertTrue(Arrays.equals(b1, b2));
     }
 
-    public void testAddPictures() throws Exception {
-        int idx;
-        Slide slide;
-        Picture pict;
+    /**
+     * Test read/write WMF
+     */
+    public void testWMF() throws Exception {
+        SlideShow ppt = new SlideShow();
 
+        Slide slide = ppt.createSlide();
+        File img = new File(cwd, "santa.wmf");
+        int idx = ppt.addPicture(img, Picture.WMF);
+        Picture pict = new Picture(idx);
+        assertEquals(idx, pict.getPictureIndex());
+        slide.addShape(pict);
+
+        //serialize and read again
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        ppt.write(out);
+        out.close();
+
+        ppt = new SlideShow(new HSLFSlideShow(new ByteArrayInputStream(out.toByteArray())));
+
+        //make sure we can read this picture shape and it refers to the correct picture data
+        Shape[] sh = ppt.getSlides()[0].getShapes();
+        assertEquals(1, sh.length);
+        pict = (Picture)sh[0];
+        assertEquals(idx, pict.getPictureIndex());
+
+        //check picture data
+        PictureData[] pictures = ppt.getPictureData();
+        //the Picture shape refers to the PictureData object in the Presentation
+        assertEquals(pict.getPictureData(), pictures[0]);
+
+        assertEquals(1, pictures.length);
+        assertEquals(Picture.WMF, pictures[0].getType());
+        assertTrue(pictures[0] instanceof WMF);
+        //compare the content of the initial file with what is stored in the PictureData
+        byte[] src_bytes = read(img);
+        byte[] ppt_bytes = pictures[0].getData();
+        assertEquals(src_bytes.length, ppt_bytes.length);
+        //in WMF the first 22 bytes - is a metafile header
+        byte[] b1 = new byte[src_bytes.length-22];
+        System.arraycopy(src_bytes, 22, b1, 0, b1.length);
+        byte[] b2 = new byte[ppt_bytes.length-22];
+        System.arraycopy(ppt_bytes, 22, b2, 0, b2.length);
+        assertTrue(Arrays.equals(b1, b2));
+    }
+
+    /**
+     * Test read/write EMF
+     */
+    public void testEMF() throws Exception {
         SlideShow ppt = new SlideShow();
 
-        idx = ppt.addPicture(new File(dirname + "/clock.jpg"), Picture.JPEG);
-        slide = ppt.createSlide();
-        pict = new Picture(idx);
+        Slide slide = ppt.createSlide();
+        File img = new File(cwd, "wrench.emf");
+        int idx = ppt.addPicture(img, Picture.EMF);
+        Picture pict = new Picture(idx);
+        assertEquals(idx, pict.getPictureIndex());
         slide.addShape(pict);
 
-        idx = ppt.addPicture(new File(dirname + "/painting.png"), Picture.PNG);
-        pict = new Picture(idx);
+        //serialize and read again
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        ppt.write(out);
+        out.close();
+
+        ppt = new SlideShow(new HSLFSlideShow(new ByteArrayInputStream(out.toByteArray())));
+
+        //make sure we can get this picture shape and it refers to the correct picture data
+        Shape[] sh = ppt.getSlides()[0].getShapes();
+        assertEquals(1, sh.length);
+        pict = (Picture)sh[0];
+        assertEquals(idx, pict.getPictureIndex());
+
+        //check picture data
+        PictureData[] pictures = ppt.getPictureData();
+        //the Picture shape refers to the PictureData object in the Presentation
+        assertEquals(pict.getPictureData(), pictures[0]);
+
+        assertEquals(1, pictures.length);
+        assertEquals(Picture.EMF, pictures[0].getType());
+        assertTrue(pictures[0] instanceof EMF);
+        //compare the content of the initial file with what is stored in the PictureData
+        byte[] src_bytes = read(img);
+        byte[] ppt_bytes = pictures[0].getData();
+        assertTrue(Arrays.equals(src_bytes, ppt_bytes));
+    }
+
+    /**
+     * Test read/write PNG
+     */
+    public void testPNG() throws Exception {
+        SlideShow ppt = new SlideShow();
+
+        Slide slide = ppt.createSlide();
+        File img = new File(cwd, "tomcat.png");
+        int idx = ppt.addPicture(img, Picture.PNG);
+        Picture pict = new Picture(idx);
+        assertEquals(idx, pict.getPictureIndex());
+        slide.addShape(pict);
+
+        //serialize and read again
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        ppt.write(out);
+        out.close();
+
+        ppt = new SlideShow(new HSLFSlideShow(new ByteArrayInputStream(out.toByteArray())));
+
+        //make sure we can read this picture shape and it refers to the correct picture data
+        Shape[] sh = ppt.getSlides()[0].getShapes();
+        assertEquals(1, sh.length);
+        pict = (Picture)sh[0];
+        assertEquals(idx, pict.getPictureIndex());
+
+        //check picture data
+        PictureData[] pictures = ppt.getPictureData();
+        //the Picture shape refers to the PictureData object in the Presentation
+        assertEquals(pict.getPictureData(), pictures[0]);
+
+        assertEquals(1, pictures.length);
+        assertEquals(Picture.PNG, pictures[0].getType());
+        assertTrue(pictures[0] instanceof PNG);
+        //compare the content of the initial file with what is stored in the PictureData
+        byte[] src_bytes = read(img);
+        byte[] ppt_bytes = pictures[0].getData();
+        assertTrue(Arrays.equals(src_bytes, ppt_bytes));
+    }
+
+    /**
+     * Test read/write JPEG
+     */
+    public void testJPEG() throws Exception {
+        SlideShow ppt = new SlideShow();
+
+        Slide slide = ppt.createSlide();
+        File img = new File(cwd, "clock.jpg");
+        int idx = ppt.addPicture(img, Picture.JPEG);
+        Picture pict = new Picture(idx);
+        assertEquals(idx, pict.getPictureIndex());
         slide.addShape(pict);
 
+        //serialize and read again
         ByteArrayOutputStream out = new ByteArrayOutputStream();
         ppt.write(out);
         out.close();
 
         ppt = new SlideShow(new HSLFSlideShow(new ByteArrayInputStream(out.toByteArray())));
-        assertTrue(ppt.getPictureData().length == 2 );
+
+        //make sure we can read this picture shape and it refers to the correct picture data
+        Shape[] sh = ppt.getSlides()[0].getShapes();
+        assertEquals(1, sh.length);
+        pict = (Picture)sh[0];
+        assertEquals(idx, pict.getPictureIndex());
+
+        //check picture data
+        PictureData[] pictures = ppt.getPictureData();
+        //the Picture shape refers to the PictureData object in the Presentation
+        assertEquals(pict.getPictureData(), pictures[0]);
+
+        assertEquals(1, pictures.length);
+        assertEquals(Picture.JPEG, pictures[0].getType());
+        assertTrue(pictures[0] instanceof JPEG);
+        //compare the content of the initial file with what is stored in the PictureData
+        byte[] src_bytes = read(img);
+        byte[] ppt_bytes = pictures[0].getData();
+        assertTrue(Arrays.equals(src_bytes, ppt_bytes));
     }
+
+    /**
+     * Read file into a byte array
+     */
+    protected byte[] read(File f) throws IOException {
+        byte[] bytes = new byte[(int)f.length()];
+        FileInputStream is = new FileInputStream(f);
+        is.read(bytes);
+        is.close();
+        return bytes;
+    }
+
+    /**
+     * Read pictures in different formats from a reference slide show
+     */
+    public void testReadPictures() throws Exception {
+
+        byte[] src_bytes, ppt_bytes, b1, b2;
+        Picture pict;
+        PictureData pdata;
+
+        SlideShow ppt = new SlideShow(new HSLFSlideShow(new File(cwd, "pictures.ppt").getPath()));
+        Slide[] slides = ppt.getSlides();
+        PictureData[] pictures = ppt.getPictureData();
+        assertEquals(5, pictures.length);
+
+        pict = (Picture)slides[0].getShapes()[0]; //the first slide contains JPEG
+        pdata = pict.getPictureData();
+        assertTrue(pdata instanceof JPEG);
+        assertEquals(Picture.JPEG, pdata.getType());
+        src_bytes = pdata.getData();
+        ppt_bytes = read(new File(cwd, "clock.jpg"));
+        assertTrue(Arrays.equals(src_bytes, ppt_bytes));
+
+        pict = (Picture)slides[1].getShapes()[0]; //the second slide contains PNG
+        pdata = pict.getPictureData();
+        assertTrue(pdata instanceof PNG);
+        assertEquals(Picture.PNG, pdata.getType());
+        src_bytes = pdata.getData();
+        ppt_bytes = read(new File(cwd, "tomcat.png"));
+        assertTrue(Arrays.equals(src_bytes, ppt_bytes));
+
+        pict = (Picture)slides[2].getShapes()[0]; //the third slide contains WMF
+        pdata = pict.getPictureData();
+        assertTrue(pdata instanceof WMF);
+        assertEquals(Picture.WMF, pdata.getType());
+        src_bytes = pdata.getData();
+        ppt_bytes = read(new File(cwd, "santa.wmf"));
+        assertEquals(src_bytes.length, ppt_bytes.length);
+        //ignore the first 22 bytes - it is a WMF metafile header
+        b1 = new byte[src_bytes.length-22];
+        System.arraycopy(src_bytes, 22, b1, 0, b1.length);
+        b2 = new byte[ppt_bytes.length-22];
+        System.arraycopy(ppt_bytes, 22, b2, 0, b2.length);
+        assertTrue(Arrays.equals(b1, b2));
+
+        pict = (Picture)slides[3].getShapes()[0]; //the forth slide contains PICT
+        pdata = pict.getPictureData();
+        assertTrue(pdata instanceof PICT);
+        assertEquals(Picture.PICT, pdata.getType());
+        src_bytes = pdata.getData();
+        ppt_bytes = read(new File(cwd, "cow.pict"));
+        assertEquals(src_bytes.length, ppt_bytes.length);
+        //ignore the first 512 bytes - it is a MAC specific crap
+        b1 = new byte[src_bytes.length-512];
+        System.arraycopy(src_bytes, 512, b1, 0, b1.length);
+        b2 = new byte[ppt_bytes.length-512];
+        System.arraycopy(ppt_bytes, 512, b2, 0, b2.length);
+        assertTrue(Arrays.equals(b1, b2));
+
+        pict = (Picture)slides[4].getShapes()[0]; //the fifth slide contains EMF
+        pdata = pict.getPictureData();
+        assertTrue(pdata instanceof EMF);
+        assertEquals(Picture.EMF, pdata.getType());
+        src_bytes = pdata.getData();
+        ppt_bytes = read(new File(cwd, "wrench.emf"));
+        assertTrue(Arrays.equals(src_bytes, ppt_bytes));
+
+    }
+
 
 }



---------------------------------------------------------------------
To unsubscribe, e-mail: poi-dev-unsubscribe@jakarta.apache.org
Mailing List:    http://jakarta.apache.org/site/mail2.html#poi
The Apache Jakarta POI Project: http://jakarta.apache.org/poi/


Mime
View raw message