]> source.dussan.org Git - poi.git/commitdiff
applied the patch submitted in Bug 41223: Simple image extraction for HSSFWorkbook
authorYegor Kozlov <yegor@apache.org>
Mon, 16 Apr 2007 10:48:20 +0000 (10:48 +0000)
committerYegor Kozlov <yegor@apache.org>
Mon, 16 Apr 2007 10:48:20 +0000 (10:48 +0000)
git-svn-id: https://svn.apache.org/repos/asf/jakarta/poi/trunk@529196 13f79535-47bb-0310-9956-ffa450edef68

src/java/org/apache/poi/hssf/usermodel/HSSFPictureData.java [new file with mode: 0644]
src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java
src/testcases/org/apache/poi/hssf/usermodel/TestHSSFPictureData.java [new file with mode: 0644]

diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFPictureData.java b/src/java/org/apache/poi/hssf/usermodel/HSSFPictureData.java
new file mode 100644 (file)
index 0000000..c47a372
--- /dev/null
@@ -0,0 +1,90 @@
+/* ====================================================================
+   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.hssf.usermodel;
+
+import org.apache.poi.ddf.EscherBitmapBlip;
+
+/**
+ * Represents binary data stored in the file.  Eg. A GIF, JPEG etc...
+ *
+ * @author Daniel Noll
+ */
+public class HSSFPictureData
+{
+    // MSOBI constants for various formats.
+    public static final short MSOBI_WMF   = 0x2160;
+    public static final short MSOBI_EMF   = 0x3D40;
+    public static final short MSOBI_PICT  = 0x5420;
+    public static final short MSOBI_PNG   = 0x6E00;
+    public static final short MSOBI_JPEG  = 0x46A0;
+    public static final short MSOBI_DIB   = 0x7A80;
+    // Mask of the bits in the options used to store the image format.
+    public static final short FORMAT_MASK = (short) 0xFFF0;
+
+    /**
+     * Underlying escher blip record containing the bitmap data.
+     */
+    private EscherBitmapBlip blip;
+
+    /**
+     * Constructs a picture object.
+     *
+     * @param blip the underlying blip record containing the bitmap data.
+     */
+    HSSFPictureData( EscherBitmapBlip blip )
+    {
+        this.blip = blip;
+    }
+
+    /**
+     * Gets the picture data.
+     *
+     * @return the picture data.
+     */
+    public byte[] getData()
+    {
+        return blip.getPicturedata();
+    }
+
+    /**
+     * Suggests a file extension for this image.
+     *
+     * @return the file extension.
+     */
+    public String suggestFileExtension()
+    {
+        switch (blip.getOptions() & FORMAT_MASK)
+        {
+            case MSOBI_WMF:
+                return "wmf";
+            case MSOBI_EMF:
+                return "emf";
+            case MSOBI_PICT:
+                return "pict";
+            case MSOBI_PNG:
+                return "png";
+            case MSOBI_JPEG:
+                return "jpeg";
+            case MSOBI_DIB:
+                return "dib";
+            default:
+                return "";
+        }
+    }
+}
+
index 9ce9f171b88af87f94bcefd1f8ab6303a6d74f4e..f90717e9866f994968c61f6292bf85cee93a0e6c 100644 (file)
@@ -26,6 +26,7 @@ package org.apache.poi.hssf.usermodel;
 import org.apache.poi.ddf.EscherBSERecord;
 import org.apache.poi.ddf.EscherBitmapBlip;
 import org.apache.poi.ddf.EscherRecord;
+import org.apache.poi.ddf.EscherBlipRecord;
 import org.apache.poi.hssf.eventmodel.EventRecordFactory;
 import org.apache.poi.hssf.model.Sheet;
 import org.apache.poi.hssf.model.Workbook;
@@ -114,14 +115,12 @@ public class HSSFWorkbook
     private HSSFDataFormat formatter;
 
 
-    /// NOT YET SUPPORTED:
     /** Extended windows meta file */
-    //public static final int PICTURE_TYPE_EMF = 2;
+    public static final int PICTURE_TYPE_EMF = 2;
     /** Windows Meta File */
-    //public static final int PICTURE_TYPE_WMF = 3;
+    public static final int PICTURE_TYPE_WMF = 3;
     /** Mac PICT format */
-    //public static final int PICTURE_TYPE_PICT = 4;
-
+    public static final int PICTURE_TYPE_PICT = 4;
     /** JPEG format */
     public static final int PICTURE_TYPE_JPEG = 5;
     /** PNG format */
@@ -217,6 +216,11 @@ public class HSSFWorkbook
             Sheet sheet = Sheet.createSheet(records, sheetNum++, recOffset );
 
             recOffset = sheet.getEofLoc()+1;
+            if (recOffset == 1)
+            {
+                break;
+            }
+
             HSSFSheet hsheet = new HSSFSheet(workbook, sheet);
 
             sheets.add(hsheet);
@@ -1274,12 +1278,27 @@ public class HSSFWorkbook
         byte[] uid = newUID();
         EscherBitmapBlip blipRecord = new EscherBitmapBlip();
         blipRecord.setRecordId( (short) ( EscherBitmapBlip.RECORD_ID_START + format ) );
-        if (format == HSSFWorkbook.PICTURE_TYPE_PNG)
-            blipRecord.setOptions( (short) 0x6E00 );  // MSOBI
-        else if (format == HSSFWorkbook.PICTURE_TYPE_JPEG)
-            blipRecord.setOptions( (short) 0x46A0 );  // MSOBI
-        else if (format == HSSFWorkbook.PICTURE_TYPE_DIB)
-            blipRecord.setOptions( (short) 0x7A8 );  // MSOBI
+        switch (format)
+        {
+            case PICTURE_TYPE_EMF:
+                blipRecord.setOptions(HSSFPictureData.MSOBI_EMF);
+                break;
+            case PICTURE_TYPE_WMF:
+                blipRecord.setOptions(HSSFPictureData.MSOBI_WMF);
+                break;
+            case PICTURE_TYPE_PICT:
+                blipRecord.setOptions(HSSFPictureData.MSOBI_PICT);
+                break;
+            case PICTURE_TYPE_PNG:
+                blipRecord.setOptions(HSSFPictureData.MSOBI_PNG);
+                break;
+            case HSSFWorkbook.PICTURE_TYPE_JPEG:
+                blipRecord.setOptions(HSSFPictureData.MSOBI_JPEG);
+                break;
+            case HSSFWorkbook.PICTURE_TYPE_DIB:
+                blipRecord.setOptions(HSSFPictureData.MSOBI_DIB);
+                break;
+        }
 
         blipRecord.setUID( uid );
         blipRecord.setMarker( (byte) 0xFF );
@@ -1300,6 +1319,60 @@ public class HSSFWorkbook
         return workbook.addBSERecord( r );
     }
 
+    /**
+     * Gets all pictures from the Workbook.
+     *
+     * @return the list of pictures (a list of {@link HSSFPictureData} objects.)
+     */
+    public List getAllPictures()
+    {
+        List pictures = new ArrayList();
+        Iterator recordIter = workbook.getRecords().iterator();
+        while (recordIter.hasNext())
+        {
+            Object obj = recordIter.next();
+            if (obj instanceof AbstractEscherHolderRecord)
+            {
+                ((AbstractEscherHolderRecord) obj).decode();
+                List escherRecords = ((AbstractEscherHolderRecord) obj).getEscherRecords();
+                searchForPictures(escherRecords, pictures);
+            }
+        }
+        return pictures;
+    }
+
+    /**
+     * Performs a recursive search for pictures in the given list of escher records.
+     *
+     * @param escherRecords the escher records.
+     * @param pictures the list to populate with the pictures.
+     */
+    private void searchForPictures(List escherRecords, List pictures)
+    {
+        Iterator recordIter = escherRecords.iterator();
+        while (recordIter.hasNext())
+        {
+            Object obj = recordIter.next();
+            if (obj instanceof EscherRecord)
+            {
+                EscherRecord escherRecord = (EscherRecord) obj;
+
+                if (escherRecord instanceof EscherBSERecord)
+                {
+                    EscherBlipRecord blip = ((EscherBSERecord) escherRecord).getBlipRecord();
+                    if (blip instanceof EscherBitmapBlip)
+                    {
+                        // TODO: Some kind of structure.
+                        pictures.add(new HSSFPictureData((EscherBitmapBlip) blip));
+                    }
+                }
+
+                // Recursive call.
+                searchForPictures(escherRecord.getChildRecords(), pictures);
+            }
+        }
+    }
+
     private byte[] newUID()
     {
         byte[] bytes = new byte[16];
diff --git a/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFPictureData.java b/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFPictureData.java
new file mode 100644 (file)
index 0000000..a31d933
--- /dev/null
@@ -0,0 +1,75 @@
+/* ====================================================================\r
+   Licensed to the Apache Software Foundation (ASF) under one or more\r
+   contributor license agreements.  See the NOTICE file distributed with\r
+   this work for additional information regarding copyright ownership.\r
+   The ASF licenses this file to You under the Apache License, Version 2.0\r
+   (the "License"); you may not use this file except in compliance with\r
+   the License.  You may obtain a copy of the License at\r
+\r
+       http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+   Unless required by applicable law or agreed to in writing, software\r
+   distributed under the License is distributed on an "AS IS" BASIS,\r
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+   See the License for the specific language governing permissions and\r
+   limitations under the License.\r
+==================================================================== */\r
+\r
+\r
+/*\r
+ * HSSFWorkbook.java\r
+ *\r
+ * Created on September 30, 2001, 3:37 PM\r
+ */\r
+package org.apache.poi.hssf.usermodel;\r
+\r
+import junit.framework.TestCase;\r
+\r
+import javax.imageio.ImageIO;\r
+import java.io.*;\r
+import java.util.*;\r
+import java.awt.image.BufferedImage;\r
+\r
+/**\r
+ * Test <code>HSSFPictureData</code>.\r
+ * The code to retrieve images from a workbook provided by Trejkaz (trejkaz at trypticon dot org) in Bug 41223.\r
+ *\r
+ * @author Yegor Kozlov (yegor at apache dot org)\r
+ * @author Trejkaz (trejkaz at trypticon dot org)\r
+ */\r
+public class TestHSSFPictureData extends TestCase{\r
+\r
+    static String cwd = System.getProperty("HSSF.testdata.path");\r
+\r
+    public void testPictures() throws IOException {\r
+        FileInputStream is = new FileInputStream(new File(cwd, "SimpleWithImages.xls"));\r
+        HSSFWorkbook wb = new HSSFWorkbook(is);\r
+        is.close();\r
+\r
+        List lst = wb.getAllPictures();\r
+        assertEquals(2, lst.size());\r
+\r
+        for (Iterator it = lst.iterator(); it.hasNext(); ) {\r
+            HSSFPictureData pict = (HSSFPictureData)it.next();\r
+            String ext = pict.suggestFileExtension();\r
+            byte[] data = pict.getData();\r
+            if (ext.equals("jpeg")){\r
+                //try to read image data using javax.imageio.* (JDK 1.4+)\r
+                BufferedImage jpg = ImageIO.read(new ByteArrayInputStream(data));\r
+                assertNotNull(jpg);\r
+                assertEquals(192, jpg.getWidth());\r
+                assertEquals(176, jpg.getHeight());\r
+            } else if (ext.equals("png")){\r
+                //try to read image data using javax.imageio.* (JDK 1.4+)\r
+                BufferedImage png = ImageIO.read(new ByteArrayInputStream(data));\r
+                assertNotNull(png);\r
+                assertEquals(300, png.getWidth());\r
+                assertEquals(300, png.getHeight());\r
+\r
+            } else {\r
+                fail("unexpected picture type: " + ext);\r
+            }\r
+        }\r
+\r
+    }\r
+}\r