You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@poi.apache.org by ye...@apache.org on 2007/04/16 12:48:22 UTC

svn commit: r529196 - in /jakarta/poi/trunk/src: java/org/apache/poi/hssf/usermodel/HSSFPictureData.java java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java testcases/org/apache/poi/hssf/usermodel/TestHSSFPictureData.java

Author: yegor
Date: Mon Apr 16 03:48:20 2007
New Revision: 529196

URL: http://svn.apache.org/viewvc?view=rev&rev=529196
Log:
applied the patch submitted in Bug 41223: Simple image extraction for HSSFWorkbook

Added:
    jakarta/poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFPictureData.java
    jakarta/poi/trunk/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFPictureData.java
Modified:
    jakarta/poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java

Added: jakarta/poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFPictureData.java
URL: http://svn.apache.org/viewvc/jakarta/poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFPictureData.java?view=auto&rev=529196
==============================================================================
--- jakarta/poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFPictureData.java (added)
+++ jakarta/poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFPictureData.java Mon Apr 16 03:48:20 2007
@@ -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 "";
+        }
+    }
+}
+

Modified: jakarta/poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java
URL: http://svn.apache.org/viewvc/jakarta/poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java?view=diff&rev=529196&r1=529195&r2=529196
==============================================================================
--- jakarta/poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java (original)
+++ jakarta/poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java Mon Apr 16 03:48:20 2007
@@ -26,6 +26,7 @@
 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 @@
     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 @@
             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 @@
         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 );
@@ -1298,6 +1317,60 @@
         r.setBlipRecord( blipRecord );
 
         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()

Added: jakarta/poi/trunk/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFPictureData.java
URL: http://svn.apache.org/viewvc/jakarta/poi/trunk/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFPictureData.java?view=auto&rev=529196
==============================================================================
--- jakarta/poi/trunk/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFPictureData.java (added)
+++ jakarta/poi/trunk/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFPictureData.java Mon Apr 16 03:48:20 2007
@@ -0,0 +1,75 @@
+/* ====================================================================
+   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.
+==================================================================== */
+
+
+/*
+ * HSSFWorkbook.java
+ *
+ * Created on September 30, 2001, 3:37 PM
+ */
+package org.apache.poi.hssf.usermodel;
+
+import junit.framework.TestCase;
+
+import javax.imageio.ImageIO;
+import java.io.*;
+import java.util.*;
+import java.awt.image.BufferedImage;
+
+/**
+ * Test <code>HSSFPictureData</code>.
+ * The code to retrieve images from a workbook provided by Trejkaz (trejkaz at trypticon dot org) in Bug 41223.
+ *
+ * @author Yegor Kozlov (yegor at apache dot org)
+ * @author Trejkaz (trejkaz at trypticon dot org)
+ */
+public class TestHSSFPictureData extends TestCase{
+
+    static String cwd = System.getProperty("HSSF.testdata.path");
+
+    public void testPictures() throws IOException {
+        FileInputStream is = new FileInputStream(new File(cwd, "SimpleWithImages.xls"));
+        HSSFWorkbook wb = new HSSFWorkbook(is);
+        is.close();
+
+        List lst = wb.getAllPictures();
+        assertEquals(2, lst.size());
+
+        for (Iterator it = lst.iterator(); it.hasNext(); ) {
+            HSSFPictureData pict = (HSSFPictureData)it.next();
+            String ext = pict.suggestFileExtension();
+            byte[] data = pict.getData();
+            if (ext.equals("jpeg")){
+                //try to read image data using javax.imageio.* (JDK 1.4+)
+                BufferedImage jpg = ImageIO.read(new ByteArrayInputStream(data));
+                assertNotNull(jpg);
+                assertEquals(192, jpg.getWidth());
+                assertEquals(176, jpg.getHeight());
+            } else if (ext.equals("png")){
+                //try to read image data using javax.imageio.* (JDK 1.4+)
+                BufferedImage png = ImageIO.read(new ByteArrayInputStream(data));
+                assertNotNull(png);
+                assertEquals(300, png.getWidth());
+                assertEquals(300, png.getHeight());
+
+            } else {
+                fail("unexpected picture type: " + ext);
+            }
+        }
+
+    }
+}



---------------------------------------------------------------------
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/