From ee6966dae9b143f20c1120367ae07137d44a1cdc Mon Sep 17 00:00:00 2001 From: Andreas Beeker Date: Thu, 31 Dec 2015 20:23:20 +0000 Subject: [PATCH] WMF fixes git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1722465 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/poi/hwmf/record/HwmfBitmap16.java | 29 +----- .../apache/poi/hwmf/record/HwmfBitmapDib.java | 73 ++++++++------ .../org/apache/poi/hwmf/record/HwmfFill.java | 6 +- .../org/apache/poi/hwmf/record/HwmfText.java | 7 +- .../apache/poi/hwmf/record/HwmfWindowing.java | 36 +++---- .../poi/hwmf/usermodel/HwmfPicture.java | 8 +- .../org/apache/poi/hwmf/TestHwmfParsing.java | 98 +++++++++++-------- 7 files changed, 128 insertions(+), 129 deletions(-) diff --git a/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfBitmap16.java b/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfBitmap16.java index c0293b433..2ff0d118a 100644 --- a/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfBitmap16.java +++ b/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfBitmap16.java @@ -76,33 +76,8 @@ public class HwmfBitmap16 { byte buf[] = new byte[bytes]; leis.read(buf); -// FileOutputStream fos = new FileOutputStream("bla16.bmp"); -// fos.write(buf); -// fos.close(); - - -// BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); -// -// int size2 = 0; -// byte buf[] = new byte[widthBytes]; -// for (int h=0; h ((recordFunction >> 8) + 3)); + boolean hasBitmap = (recordSize/2 != ((recordFunction >> 8) + 3)); int size = 0; int rasterOpCode = leis.readUShort(); @@ -802,7 +802,7 @@ public class HwmfFill { @Override public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException { - boolean hasBitmap = (recordSize > ((recordFunction >> 8) + 3)); + boolean hasBitmap = (recordSize/2 != ((recordFunction >> 8) + 3)); int size = 0; int rasterOpCode = leis.readUShort(); @@ -840,7 +840,7 @@ public class HwmfFill { @Override public BufferedImage getImage() { - return target.getImage(); + return (target == null) ? null : target.getImage(); } } diff --git a/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfText.java b/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfText.java index 6d332607f..5e6dde83a 100644 --- a/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfText.java +++ b/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfText.java @@ -259,6 +259,9 @@ public class HwmfText { @Override public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException { + // -6 bytes of record function and length header + final int remainingRecordSize = (int)(recordSize-6); + y = leis.readShort(); x = leis.readShort(); stringLength = leis.readShort(); @@ -266,7 +269,7 @@ public class HwmfText { int size = 4*LittleEndianConsts.SHORT_SIZE; - if (fwOpts != 0) { + if (fwOpts != 0 && size+8<=remainingRecordSize) { // the bounding rectangle is optional and only read when fwOpts are given left = leis.readShort(); top = leis.readShort(); @@ -280,8 +283,6 @@ public class HwmfText { text = new String(buf, 0, stringLength, LocaleUtil.CHARSET_1252); size += buf.length; - // -6 bytes of record function and length header - int remainingRecordSize = (int)(recordSize-6); if (size < remainingRecordSize) { if (size + stringLength*LittleEndianConsts.SHORT_SIZE < remainingRecordSize) { throw new RecordFormatException("can't read Dx array - given recordSize doesn't contain enough values for string length "+stringLength); diff --git a/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfWindowing.java b/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfWindowing.java index 1cb19e005..a6d720458 100644 --- a/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfWindowing.java +++ b/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfWindowing.java @@ -542,14 +542,17 @@ public class HwmfWindowing { count = leis.readUShort(); top = leis.readUShort(); bottom = leis.readUShort(); - left_scanline = new int[count]; - right_scanline = new int[count]; - for (int i=0; i*2 soList = new ArrayList(); - int scanCountI = 0, size = 0; - do { - WmfScanObject so = new WmfScanObject(); - size += so.init(leis); - scanCountI += so.count; - soList.add(so); - } while (scanCountI < scanCount); - scanObjects = soList.toArray(new WmfScanObject[soList.size()]); + scanObjects = new WmfScanObject[scanCount]; + for (int i=0; i= 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); + // skip size in loops, because not always all bytes are skipped in one call + for (int i=remainingSize; i>0; i-=leis.skip(i)); } } } diff --git a/src/scratchpad/testcases/org/apache/poi/hwmf/TestHwmfParsing.java b/src/scratchpad/testcases/org/apache/poi/hwmf/TestHwmfParsing.java index a1f2cbf1d..ad585eccb 100644 --- a/src/scratchpad/testcases/org/apache/poi/hwmf/TestHwmfParsing.java +++ b/src/scratchpad/testcases/org/apache/poi/hwmf/TestHwmfParsing.java @@ -20,14 +20,17 @@ 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.FilterInputStream; import java.io.IOException; +import java.net.URL; import java.util.List; import java.util.Locale; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; import javax.imageio.ImageIO; @@ -55,55 +58,70 @@ public class TestHwmfParsing { @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; - + public void fetchWmfFromGovdocs() throws IOException { + URL url = new URL("http://digitalcorpora.org/corpora/files/govdocs1/by_type/ppt.zip"); File outdir = new File("build/ppt"); - if (outputFiles) { - outdir.mkdirs(); - } - int wmfIdx = 1; - for (File f : files) { + outdir.mkdirs(); + ZipInputStream zis = new ZipInputStream(url.openStream()); + ZipEntry ze; + while ((ze = zis.getNextEntry()) != null) { + String basename = ze.getName().replaceAll(".*?([^/]+)\\.wmf", "$1"); + FilterInputStream fis = new FilterInputStream(zis){ + public void close() throws IOException {} + }; try { - SlideShow ss = SlideShowFactory.create(f); + SlideShow ss = SlideShowFactory.create(fis); + int wmfIdx = 1; 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++; - } - } - + String filename = String.format(Locale.ROOT, "%s-%04d.wmf", basename, wmfIdx); + FileOutputStream fos = new FileOutputStream(new File(outdir, filename)); + fos.write(wmfData); + fos.close(); wmfIdx++; } ss.close(); } catch (Exception e) { - System.out.println(f+" ignored."); + System.out.println(ze.getName()+" ignored."); + } + } + } + + @Test + @Ignore + public void parseWmfs() throws IOException { + boolean outputFiles = false; + File indir = new File("build/ppt"), outdir = indir; + final String startFile = ""; + File files[] = indir.listFiles(new FileFilter() { + boolean foundStartFile = false; + public boolean accept(File pathname) { + foundStartFile |= startFile.isEmpty() || pathname.getName().contains(startFile); + return foundStartFile && pathname.getName().matches("(?i).*\\.wmf?$"); + } + }); + for (File f : files) { + try { + String basename = f.getName().replaceAll(".*?([^/]+)\\.wmf", "$1"); + FileInputStream fis = new FileInputStream(f); + HwmfPicture wmf = new HwmfPicture(fis); + fis.close(); + + int bmpIndex = 1; + for (HwmfRecord r : wmf.getRecords()) { + if (r instanceof HwmfImageRecord) { + BufferedImage bi = ((HwmfImageRecord)r).getImage(); + if (bi != null && outputFiles) { + String filename = String.format(Locale.ROOT, "%s-%04d.png", basename, bmpIndex); + ImageIO.write(bi, "PNG", new File(outdir, filename)); + } + bmpIndex++; + } + } + } catch (Exception e) { + System.out.println(f.getName()+" ignored."); } } } - }