You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@poi.apache.org by ki...@apache.org on 2015/12/29 01:45:59 UTC

svn commit: r1722046 [3/3] - in /poi/trunk/src/scratchpad: src/org/apache/poi/hwmf/draw/ src/org/apache/poi/hwmf/record/ src/org/apache/poi/hwmf/usermodel/ testcases/org/apache/poi/hwmf/

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfWindowing.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfWindowing.java?rev=1722046&r1=1722045&r2=1722046&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfWindowing.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfWindowing.java Tue Dec 29 00:45:59 2015
@@ -17,44 +17,18 @@
 
 package org.apache.poi.hwmf.record;
 
+import java.awt.geom.Rectangle2D;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
 
+import org.apache.poi.hwmf.draw.HwmfGraphics;
 import org.apache.poi.util.LittleEndianConsts;
 import org.apache.poi.util.LittleEndianInputStream;
 
 public class HwmfWindowing {
 
     /**
-     * The META_OFFSETCLIPRGN record moves the clipping region in the playback device context by the
-     * specified offsets.
-     */
-    public static class WmfOffsetClipRgn implements HwmfRecord {
-
-        /**
-         * A 16-bit signed integer that defines the number of logical units to move up or down.
-         */
-        int yOffset;
-
-        /**
-         * A 16-bit signed integer that defines the number of logical units to move left or right.
-         */
-        int xOffset;
-
-        public HwmfRecordType getRecordType() {
-            return HwmfRecordType.offsetClipRgn;
-        }
-
-        public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
-            yOffset = leis.readShort();
-            xOffset = leis.readShort();
-            return 2*LittleEndianConsts.SHORT_SIZE;
-        }
-    }
-
-
-    /**
      * The META_SETVIEWPORTORG record defines the viewport origin in the playback device context.
      */
     public static class WmfSetViewportOrg implements HwmfRecord {
@@ -62,22 +36,29 @@ public class HwmfWindowing {
         /**
          * A 16-bit signed integer that defines the vertical offset, in device units.
          */
-        int y;
+        private int y;
 
         /**
          * A 16-bit signed integer that defines the horizontal offset, in device units.
          */
-        int x;
+        private int x;
 
+        @Override
         public HwmfRecordType getRecordType() {
             return HwmfRecordType.setViewportOrg;
         }
 
+        @Override
         public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
             y = leis.readShort();
             x = leis.readShort();
             return 2*LittleEndianConsts.SHORT_SIZE;
         }
+
+        @Override
+        public void draw(HwmfGraphics ctx) {
+            ctx.getProperties().setViewportOrg(x, y);
+        }
     }
 
     /**
@@ -90,23 +71,30 @@ public class HwmfWindowing {
          * A 16-bit signed integer that defines the vertical extent
          * of the viewport in device units.
          */
-        int y;
+        private int height;
 
         /**
          * A 16-bit signed integer that defines the horizontal extent
          * of the viewport in device units.
          */
-        int x;
+        private int width;
 
+        @Override
         public HwmfRecordType getRecordType() {
             return HwmfRecordType.setViewportExt;
         }
 
+        @Override
         public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
-            y = leis.readShort();
-            x = leis.readShort();
+            height = leis.readShort();
+            width = leis.readShort();
             return 2*LittleEndianConsts.SHORT_SIZE;
         }
+
+        @Override
+        public void draw(HwmfGraphics ctx) {
+            ctx.getProperties().setViewportExt(width, height);
+        }
     }
 
     /**
@@ -118,22 +106,30 @@ public class HwmfWindowing {
         /**
          * A 16-bit signed integer that defines the vertical offset, in device units.
          */
-        int yOffset;
+        private int yOffset;
 
         /**
          * A 16-bit signed integer that defines the horizontal offset, in device units.
          */
-        int xOffset;
+        private int xOffset;
 
+        @Override
         public HwmfRecordType getRecordType() {
             return HwmfRecordType.offsetViewportOrg;
         }
 
+        @Override
         public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
             yOffset = leis.readShort();
             xOffset = leis.readShort();
             return 2*LittleEndianConsts.SHORT_SIZE;
         }
+
+        @Override
+        public void draw(HwmfGraphics ctx) {
+            Rectangle2D viewport = ctx.getProperties().getViewport();
+            ctx.getProperties().setViewportOrg(viewport.getX()+xOffset, viewport.getY()+yOffset);
+        }
     }
 
     /**
@@ -144,22 +140,29 @@ public class HwmfWindowing {
         /**
          * A 16-bit signed integer that defines the y-coordinate, in logical units.
          */
-        int y;
+        private int y;
 
         /**
          * A 16-bit signed integer that defines the x-coordinate, in logical units.
          */
-        int x;
+        private int x;
 
+        @Override
         public HwmfRecordType getRecordType() {
             return HwmfRecordType.setWindowOrg;
         }
 
+        @Override
         public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
             y = leis.readShort();
             x = leis.readShort();
             return 2*LittleEndianConsts.SHORT_SIZE;
         }
+
+        @Override
+        public void draw(HwmfGraphics ctx) {
+            ctx.getProperties().setWindowOrg(x, y);
+        }
     }
 
     /**
@@ -172,23 +175,30 @@ public class HwmfWindowing {
          * A 16-bit signed integer that defines the vertical extent of
          * the window in logical units.
          */
-        int y;
+        private int height;
 
         /**
          * A 16-bit signed integer that defines the horizontal extent of
          * the window in logical units.
          */
-        int x;
+        private int width;
 
+        @Override
         public HwmfRecordType getRecordType() {
             return HwmfRecordType.setWindowExt;
         }
 
+        @Override
         public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
-            y = leis.readShort();
-            x = leis.readShort();
+            height = leis.readShort();
+            width = leis.readShort();
             return 2*LittleEndianConsts.SHORT_SIZE;
         }
+
+        @Override
+        public void draw(HwmfGraphics ctx) {
+            ctx.getProperties().setWindowExt(width, height);
+        }
     }
 
     /**
@@ -200,22 +210,30 @@ public class HwmfWindowing {
         /**
          * A 16-bit signed integer that defines the vertical offset, in device units.
          */
-        int yOffset;
+        private int yOffset;
 
         /**
          * A 16-bit signed integer that defines the horizontal offset, in device units.
          */
-        int xOffset;
+        private int xOffset;
 
+        @Override
         public HwmfRecordType getRecordType() {
             return HwmfRecordType.offsetWindowOrg;
         }
 
+        @Override
         public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
             yOffset = leis.readShort();
             xOffset = leis.readShort();
             return 2*LittleEndianConsts.SHORT_SIZE;
         }
+
+        @Override
+        public void draw(HwmfGraphics ctx) {
+            Rectangle2D window = ctx.getProperties().getWindow();
+            ctx.getProperties().setWindowOrg(window.getX()+xOffset, window.getY()+yOffset);
+        }
     }
 
     /**
@@ -228,30 +246,32 @@ public class HwmfWindowing {
          * A 16-bit signed integer that defines the amount by which to divide the
          * result of multiplying the current y-extent by the value of the yNum member.
          */
-        int yDenom;
+        private int yDenom;
 
         /**
          * A 16-bit signed integer that defines the amount by which to multiply the
          * current y-extent.
          */
-        int yNum;
+        private int yNum;
 
         /**
          * A 16-bit signed integer that defines the amount by which to divide the
          * result of multiplying the current x-extent by the value of the xNum member.
          */
-        int xDenom;
+        private int xDenom;
 
         /**
          * A 16-bit signed integer that defines the amount by which to multiply the
          * current x-extent.
          */
-        int xNum;
+        private int xNum;
 
+        @Override
         public HwmfRecordType getRecordType() {
             return HwmfRecordType.scaleWindowExt;
         }
 
+        @Override
         public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
             yDenom = leis.readShort();
             yNum = leis.readShort();
@@ -259,6 +279,14 @@ public class HwmfWindowing {
             xNum = leis.readShort();
             return 4*LittleEndianConsts.SHORT_SIZE;
         }
+
+        @Override
+        public void draw(HwmfGraphics ctx) {
+            Rectangle2D window = ctx.getProperties().getWindow();
+            double width = window.getWidth() * xNum / xDenom;
+            double height = window.getHeight() * yNum / yDenom;
+            ctx.getProperties().setWindowExt(width, height);
+        }
     }
 
 
@@ -273,30 +301,32 @@ public class HwmfWindowing {
          * A 16-bit signed integer that defines the amount by which to divide the
          * result of multiplying the current y-extent by the value of the yNum member.
          */
-        int yDenom;
+        private int yDenom;
 
         /**
          * A 16-bit signed integer that defines the amount by which to multiply the
          * current y-extent.
          */
-        int yNum;
+        private int yNum;
 
         /**
          * A 16-bit signed integer that defines the amount by which to divide the
          * result of multiplying the current x-extent by the value of the xNum member.
          */
-        int xDenom;
+        private int xDenom;
 
         /**
          * A 16-bit signed integer that defines the amount by which to multiply the
          * current x-extent.
          */
-        int xNum;
+        private int xNum;
 
+        @Override
         public HwmfRecordType getRecordType() {
             return HwmfRecordType.scaleViewportExt;
         }
 
+        @Override
         public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
             yDenom = leis.readShort();
             yNum = leis.readShort();
@@ -304,6 +334,48 @@ public class HwmfWindowing {
             xNum = leis.readShort();
             return 4*LittleEndianConsts.SHORT_SIZE;
         }
+
+        @Override
+        public void draw(HwmfGraphics ctx) {
+            Rectangle2D viewport = ctx.getProperties().getViewport();
+            double width = viewport.getWidth() * xNum / xDenom;
+            double height = viewport.getHeight() * yNum / yDenom;
+            ctx.getProperties().setViewportExt(width, height);
+        }
+    }
+
+    /**
+     * The META_OFFSETCLIPRGN record moves the clipping region in the playback device context by the
+     * specified offsets.
+     */
+    public static class WmfOffsetClipRgn implements HwmfRecord {
+
+        /**
+         * A 16-bit signed integer that defines the number of logical units to move up or down.
+         */
+        private int yOffset;
+
+        /**
+         * A 16-bit signed integer that defines the number of logical units to move left or right.
+         */
+        private int xOffset;
+
+        @Override
+        public HwmfRecordType getRecordType() {
+            return HwmfRecordType.offsetClipRgn;
+        }
+
+        @Override
+        public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
+            yOffset = leis.readShort();
+            xOffset = leis.readShort();
+            return 2*LittleEndianConsts.SHORT_SIZE;
+        }
+
+        @Override
+        public void draw(HwmfGraphics ctx) {
+
+        }
     }
 
     /**
@@ -316,30 +388,32 @@ public class HwmfWindowing {
          * A 16-bit signed integer that defines the y-coordinate, in logical units, of the
          * lower-right corner of the rectangle.
          */
-        int bottom;
+        private int bottom;
 
         /**
          * A 16-bit signed integer that defines the x-coordinate, in logical units, of the
          * lower-right corner of the rectangle.
          */
-        int right;
+        private int right;
 
         /**
          * A 16-bit signed integer that defines the y-coordinate, in logical units, of the
          * upper-left corner of the rectangle.
          */
-        int top;
+        private int top;
 
         /**
          * A 16-bit signed integer that defines the x-coordinate, in logical units, of the
          * upper-left corner of the rectangle.
          */
-        int left;
+        private int left;
 
+        @Override
         public HwmfRecordType getRecordType() {
             return HwmfRecordType.excludeClipRect;
         }
 
+        @Override
         public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
             bottom = leis.readShort();
             right = leis.readShort();
@@ -347,6 +421,11 @@ public class HwmfWindowing {
             left = leis.readShort();
             return 4*LittleEndianConsts.SHORT_SIZE;
         }
+
+        @Override
+        public void draw(HwmfGraphics ctx) {
+
+        }
     }
 
 
@@ -360,30 +439,32 @@ public class HwmfWindowing {
          * A 16-bit signed integer that defines the y-coordinate, in logical units, of the
          * lower-right corner of the rectangle.
          */
-        int bottom;
+        private int bottom;
 
         /**
          * A 16-bit signed integer that defines the x-coordinate, in logical units, of the
          * lower-right corner of the rectangle.
          */
-        int right;
+        private int right;
 
         /**
          * A 16-bit signed integer that defines the y-coordinate, in logical units, of the
          * upper-left corner of the rectangle.
          */
-        int top;
+        private int top;
 
         /**
          * A 16-bit signed integer that defines the x-coordinate, in logical units, of the
          * upper-left corner of the rectangle.
          */
-        int left;
+        private int left;
 
+        @Override
         public HwmfRecordType getRecordType() {
             return HwmfRecordType.intersectClipRect;
         }
 
+        @Override
         public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
             bottom = leis.readShort();
             right = leis.readShort();
@@ -391,11 +472,15 @@ public class HwmfWindowing {
             left = leis.readShort();
             return 4*LittleEndianConsts.SHORT_SIZE;
         }
+
+        @Override
+        public void draw(HwmfGraphics ctx) {
+
+        }
     }
 
     /**
-     * The META_INTERSECTCLIPRECT record sets the clipping region in the playback device context to the
-     * intersection of the existing clipping region and the specified rectangle.
+     * The META_SELECTCLIPREGION record specifies a Region Object to be the current clipping region.
      */
     public static class WmfSelectClipRegion implements HwmfRecord {
 
@@ -403,16 +488,23 @@ public class HwmfWindowing {
          * A 16-bit unsigned integer used to index into the WMF Object Table to get
          * the region to be clipped.
          */
-        int region;
+        private int region;
 
+        @Override
         public HwmfRecordType getRecordType() {
             return HwmfRecordType.selectClipRegion;
         }
 
+        @Override
         public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
             region = leis.readShort();
             return LittleEndianConsts.SHORT_SIZE;
         }
+
+        @Override
+        public void draw(HwmfGraphics ctx) {
+
+        }
     }
 
     public static class WmfScanObject {
@@ -421,30 +513,30 @@ public class HwmfWindowing {
          * coordinates in the ScanLines array. This value MUST be a multiple of 2, since left and right
          * endpoints are required to specify each scanline.
          */
-        int count;
+        private int count;
         /**
          * A 16-bit unsigned integer that defines the vertical (y-axis) coordinate, in logical units, of the top scanline.
          */
-        int top;
+        private int top;
         /**
          * A 16-bit unsigned integer that defines the vertical (y-axis) coordinate, in logical units, of the bottom scanline.
          */
-        int bottom;
+        private int bottom;
         /**
          * A 16-bit unsigned integer that defines the horizontal (x-axis) coordinate,
          * in logical units, of the left endpoint of the scanline.
          */
-        int left_scanline[];
+        private int left_scanline[];
         /**
          * A 16-bit unsigned integer that defines the horizontal (x-axis) coordinate,
          * in logical units, of the right endpoint of the scanline.
          */
-        int right_scanline[];
+        private int right_scanline[];
         /**
          * A 16-bit unsigned integer that MUST be the same as the value of the Count
          * field; it is present to allow upward travel in the structure.
          */
-        int count2;
+        private int count2;
 
         public int init(LittleEndianInputStream leis) {
             count = leis.readUShort();
@@ -465,62 +557,64 @@ public class HwmfWindowing {
         /**
          * A 16-bit signed integer. A value that MUST be ignored.
          */
-        int nextInChain;
+        private int nextInChain;
         /**
          * A 16-bit signed integer that specifies the region identifier. It MUST be 0x0006.
          */
-        int objectType;
+        private int objectType;
         /**
          * A 32-bit unsigned integer. A value that MUST be ignored.
          */
-        int objectCount;
+        private int objectCount;
         /**
          * A 16-bit signed integer that defines the size of the region in bytes plus the size of aScans in bytes.
          */
-        int regionSize;
+        private int regionSize;
         /**
          * A 16-bit signed integer that defines the number of scanlines composing the region.
          */
-        int scanCount;
+        private int scanCount;
 
         /**
          * A 16-bit signed integer that defines the maximum number of points in any one scan in this region.
          */
-        int maxScan;
+        private int maxScan;
 
         /**
          * A 16-bit signed integer that defines the y-coordinate, in logical units, of the
          * lower-right corner of the rectangle.
          */
-        int bottom;
+        private int bottom;
 
         /**
          * A 16-bit signed integer that defines the x-coordinate, in logical units, of the
          * lower-right corner of the rectangle.
          */
-        int right;
+        private int right;
 
         /**
          * A 16-bit signed integer that defines the y-coordinate, in logical units, of the
          * upper-left corner of the rectangle.
          */
-        int top;
+        private int top;
 
         /**
          * A 16-bit signed integer that defines the x-coordinate, in logical units, of the
          * upper-left corner of the rectangle.
          */
-        int left;
+        private int left;
 
         /**
          * An array of Scan objects that define the scanlines in the region.
          */
-        WmfScanObject scanObjects[];
+        private WmfScanObject scanObjects[];
 
+        @Override
         public HwmfRecordType getRecordType() {
             return HwmfRecordType.createRegion;
         }
 
+        @Override
         public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
             nextInChain = leis.readShort();
             objectType = leis.readShort();
@@ -545,5 +639,10 @@ public class HwmfWindowing {
 
             return 20 + size;
         }
+
+        @Override
+        public void draw(HwmfGraphics ctx) {
+
+        }
     }
 }

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/usermodel/HwmfPicture.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/usermodel/HwmfPicture.java?rev=1722046&r1=1722045&r2=1722046&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/usermodel/HwmfPicture.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/usermodel/HwmfPicture.java Tue Dec 29 00:45:59 2015
@@ -17,6 +17,8 @@
 
 package org.apache.poi.hwmf.usermodel;
 
+import java.io.BufferedInputStream;
+import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.util.ArrayList;
@@ -37,7 +39,8 @@ public class HwmfPicture {
     }
     
     public HwmfPicture(InputStream inputStream) throws IOException {
-        LittleEndianInputStream leis = new LittleEndianInputStream(inputStream);
+        BufferedInputStream bis = new BufferedInputStream(inputStream, 10000);
+        LittleEndianInputStream leis = new LittleEndianInputStream(bis);
         HwmfPlaceableHeader placeableHeader = HwmfPlaceableHeader.readHeader(leis);
         HwmfHeader header = new HwmfHeader(leis);
         
@@ -65,8 +68,15 @@ public class HwmfPicture {
             }
             
             consumedSize += wr.init(leis, recordSize, recordFunction);
-            if (consumedSize < recordSize) {
-                leis.skip(recordSize - consumedSize);
+            int remainingSize = (int)(recordSize - consumedSize);
+            assert(remainingSize >= 0);
+            if (remainingSize > 0) {
+                byte remaining[] = new byte[remainingSize];
+                leis.read(remaining);
+                FileOutputStream fos = new FileOutputStream("remaining.dat");
+                fos.write(remaining);
+                fos.close();
+//                 leis.skip(remainingSize);
             }
         }
     }

Modified: poi/trunk/src/scratchpad/testcases/org/apache/poi/hwmf/TestHwmfParsing.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/testcases/org/apache/poi/hwmf/TestHwmfParsing.java?rev=1722046&r1=1722045&r2=1722046&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/testcases/org/apache/poi/hwmf/TestHwmfParsing.java (original)
+++ poi/trunk/src/scratchpad/testcases/org/apache/poi/hwmf/TestHwmfParsing.java Tue Dec 29 00:45:59 2015
@@ -19,14 +19,27 @@ package org.apache.poi.hwmf;
 
 import static org.junit.Assert.assertEquals;
 
+import java.awt.image.BufferedImage;
+import java.io.ByteArrayInputStream;
 import java.io.File;
+import java.io.FileFilter;
 import java.io.FileInputStream;
+import java.io.FileOutputStream;
 import java.io.IOException;
 import java.util.List;
+import java.util.Locale;
+
+import javax.imageio.ImageIO;
 
 import org.apache.poi.POIDataSamples;
+import org.apache.poi.hwmf.record.HwmfFill.HwmfImageRecord;
 import org.apache.poi.hwmf.record.HwmfRecord;
 import org.apache.poi.hwmf.usermodel.HwmfPicture;
+import org.apache.poi.sl.usermodel.PictureData;
+import org.apache.poi.sl.usermodel.PictureData.PictureType;
+import org.apache.poi.sl.usermodel.SlideShow;
+import org.apache.poi.sl.usermodel.SlideShowFactory;
+import org.junit.Ignore;
 import org.junit.Test;
 
 public class TestHwmfParsing {
@@ -39,4 +52,58 @@ public class TestHwmfParsing {
         List<HwmfRecord> records = wmf.getRecords();
         assertEquals(581, records.size());
     }
+
+    @Test
+    @Ignore
+    public void extract() throws IOException {
+        File dir = new File("test-data/slideshow");
+        File files[] = dir.listFiles(new FileFilter() {
+            public boolean accept(File pathname) {
+                return pathname.getName().matches("(?i).*\\.pptx?$");
+            }
+        });
+
+        boolean outputFiles = false;
+
+        File outdir = new File("build/ppt");
+        if (outputFiles) {
+            outdir.mkdirs();
+        }
+        int wmfIdx = 1;
+        for (File f : files) {
+            try {
+                SlideShow<?,?> ss = SlideShowFactory.create(f);
+                for (PictureData pd : ss.getPictureData()) {
+                    if (pd.getType() != PictureType.WMF) continue;
+                    byte wmfData[] = pd.getData();
+                    if (outputFiles) {
+                        String filename = String.format(Locale.ROOT, "pic%04d.wmf", wmfIdx);
+                        FileOutputStream fos = new FileOutputStream(new File(outdir, filename));
+                        fos.write(wmfData);
+                        fos.close();
+                    }
+
+                    HwmfPicture wmf = new HwmfPicture(new ByteArrayInputStream(wmfData));
+
+                    int bmpIndex = 1;
+                    for (HwmfRecord r : wmf.getRecords()) {
+                        if (r instanceof HwmfImageRecord) {
+                            BufferedImage bi = ((HwmfImageRecord)r).getImage();
+                            if (outputFiles) {
+                                String filename = String.format(Locale.ROOT, "pic%04d-%04d.png", wmfIdx, bmpIndex);
+                                ImageIO.write(bi, "PNG", new File(outdir, filename));
+                            }
+                            bmpIndex++;
+                        }
+                    }
+
+                    wmfIdx++;
+                }
+                ss.close();
+            } catch (Exception e) {
+                System.out.println(f+" ignored.");
+            }
+        }
+    }
+
 }



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@poi.apache.org
For additional commands, e-mail: commits-help@poi.apache.org