You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

TestHwmfParsing.java 11KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. /* ====================================================================
  2. Licensed to the Apache Software Foundation (ASF) under one or more
  3. contributor license agreements. See the NOTICE file distributed with
  4. this work for additional information regarding copyright ownership.
  5. The ASF licenses this file to You under the Apache License, Version 2.0
  6. (the "License"); you may not use this file except in compliance with
  7. the License. You may obtain a copy of the License at
  8. http://www.apache.org/licenses/LICENSE-2.0
  9. Unless required by applicable law or agreed to in writing, software
  10. distributed under the License is distributed on an "AS IS" BASIS,
  11. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. See the License for the specific language governing permissions and
  13. limitations under the License.
  14. ==================================================================== */
  15. package org.apache.poi.hwmf;
  16. import static org.apache.poi.POITestCase.assertContains;
  17. import static org.junit.Assert.assertEquals;
  18. import javax.imageio.ImageIO;
  19. import java.awt.Dimension;
  20. import java.awt.Graphics2D;
  21. import java.awt.RenderingHints;
  22. import java.awt.geom.Rectangle2D;
  23. import java.awt.image.BufferedImage;
  24. import java.io.File;
  25. import java.io.FileFilter;
  26. import java.io.FileInputStream;
  27. import java.io.FileOutputStream;
  28. import java.io.FilterInputStream;
  29. import java.io.IOException;
  30. import java.io.InputStream;
  31. import java.net.URL;
  32. import java.nio.charset.Charset;
  33. import java.util.List;
  34. import java.util.Locale;
  35. import java.util.zip.ZipEntry;
  36. import java.util.zip.ZipInputStream;
  37. import org.apache.poi.POIDataSamples;
  38. import org.apache.poi.hwmf.record.HwmfFill.HwmfImageRecord;
  39. import org.apache.poi.hwmf.record.HwmfFont;
  40. import org.apache.poi.hwmf.record.HwmfRecord;
  41. import org.apache.poi.hwmf.record.HwmfRecordType;
  42. import org.apache.poi.hwmf.record.HwmfText;
  43. import org.apache.poi.hwmf.usermodel.HwmfPicture;
  44. import org.apache.poi.sl.usermodel.PictureData;
  45. import org.apache.poi.sl.usermodel.PictureData.PictureType;
  46. import org.apache.poi.sl.usermodel.SlideShow;
  47. import org.apache.poi.sl.usermodel.SlideShowFactory;
  48. import org.apache.poi.util.LocaleUtil;
  49. import org.apache.poi.util.RecordFormatException;
  50. import org.apache.poi.util.Units;
  51. import org.junit.Ignore;
  52. import org.junit.Test;
  53. public class TestHwmfParsing {
  54. private static final POIDataSamples samples = POIDataSamples.getSlideShowInstance();
  55. @Test
  56. public void parse() throws IOException {
  57. try (InputStream fis = samples.openResourceAsStream("santa.wmf")) {
  58. HwmfPicture wmf = new HwmfPicture(fis);
  59. List<HwmfRecord> records = wmf.getRecords();
  60. assertEquals(581, records.size());
  61. }
  62. }
  63. @Test(expected = RecordFormatException.class)
  64. public void testInfiniteLoop() throws Exception {
  65. try (InputStream is = samples.openResourceAsStream("61338.wmf")) {
  66. new HwmfPicture(is);
  67. }
  68. }
  69. @Test
  70. @Ignore("This is work-in-progress and not a real unit test ...")
  71. public void paint() throws IOException {
  72. File f = samples.getFile("santa.wmf");
  73. // File f = new File("bla.wmf");
  74. FileInputStream fis = new FileInputStream(f);
  75. HwmfPicture wmf = new HwmfPicture(fis);
  76. fis.close();
  77. Dimension dim = wmf.getSize();
  78. int width = Units.pointsToPixel(dim.getWidth());
  79. // keep aspect ratio for height
  80. int height = Units.pointsToPixel(dim.getHeight());
  81. double max = Math.max(width, height);
  82. if (max > 1500) {
  83. width *= 1500/max;
  84. height *= 1500/max;
  85. }
  86. BufferedImage bufImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
  87. Graphics2D g = bufImg.createGraphics();
  88. g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
  89. g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
  90. g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
  91. g.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
  92. wmf.draw(g, new Rectangle2D.Double(0,0,width,height));
  93. g.dispose();
  94. ImageIO.write(bufImg, "PNG", new File("bla.png"));
  95. }
  96. @Test
  97. @Ignore("This is work-in-progress and not a real unit test ...")
  98. public void fetchWmfFromGovdocs() throws IOException {
  99. URL url = new URL("http://digitalcorpora.org/corpora/files/govdocs1/by_type/ppt.zip");
  100. File outdir = new File("build/ppt");
  101. outdir.mkdirs();
  102. ZipInputStream zis = new ZipInputStream(url.openStream());
  103. ZipEntry ze;
  104. while ((ze = zis.getNextEntry()) != null) {
  105. String basename = ze.getName().replaceAll(".*?([^/]+)\\.wmf", "$1");
  106. FilterInputStream fis = new FilterInputStream(zis){
  107. @Override
  108. public void close() throws IOException {}
  109. };
  110. try {
  111. SlideShow<?,?> ss = SlideShowFactory.create(fis);
  112. int wmfIdx = 1;
  113. for (PictureData pd : ss.getPictureData()) {
  114. if (pd.getType() != PictureType.WMF) {
  115. continue;
  116. }
  117. byte wmfData[] = pd.getData();
  118. String filename = String.format(Locale.ROOT, "%s-%04d.wmf", basename, wmfIdx);
  119. FileOutputStream fos = new FileOutputStream(new File(outdir, filename));
  120. fos.write(wmfData);
  121. fos.close();
  122. wmfIdx++;
  123. }
  124. ss.close();
  125. } catch (Exception e) {
  126. System.out.println(ze.getName()+" ignored.");
  127. }
  128. }
  129. }
  130. @Test
  131. @Ignore("This is work-in-progress and not a real unit test ...")
  132. public void parseWmfs() throws IOException {
  133. // parse and render the extracted wmfs from the fetchWmfFromGovdocs step
  134. boolean outputFiles = false;
  135. boolean renderWmf = true;
  136. File indir = new File("E:\\project\\poi\\misc\\govdocs-ppt");
  137. File outdir = new File("build/wmf");
  138. outdir.mkdirs();
  139. final String startFile = "";
  140. File files[] = indir.listFiles(new FileFilter() {
  141. boolean foundStartFile;
  142. @Override
  143. public boolean accept(File pathname) {
  144. foundStartFile |= startFile.isEmpty() || pathname.getName().contains(startFile);
  145. return foundStartFile && pathname.getName().matches("(?i).*\\.wmf?$");
  146. }
  147. });
  148. for (File f : files) {
  149. try {
  150. String basename = f.getName().replaceAll(".*?([^/]+)\\.wmf", "$1");
  151. FileInputStream fis = new FileInputStream(f);
  152. HwmfPicture wmf = new HwmfPicture(fis);
  153. fis.close();
  154. int bmpIndex = 1;
  155. for (HwmfRecord r : wmf.getRecords()) {
  156. if (r instanceof HwmfImageRecord) {
  157. BufferedImage bi = ((HwmfImageRecord)r).getImage();
  158. if (bi != null && outputFiles) {
  159. String filename = String.format(Locale.ROOT, "%s-%04d.png", basename, bmpIndex);
  160. ImageIO.write(bi, "PNG", new File(outdir, filename));
  161. }
  162. bmpIndex++;
  163. }
  164. }
  165. if (renderWmf) {
  166. Dimension dim = wmf.getSize();
  167. int width = Units.pointsToPixel(dim.getWidth());
  168. // keep aspect ratio for height
  169. int height = Units.pointsToPixel(dim.getHeight());
  170. BufferedImage bufImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
  171. Graphics2D g = bufImg.createGraphics();
  172. g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
  173. g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
  174. g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
  175. g.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
  176. wmf.draw(g);
  177. g.dispose();
  178. ImageIO.write(bufImg, "PNG", new File(outdir, basename+".png"));
  179. }
  180. } catch (Exception e) {
  181. System.out.println(f.getName()+" ignored.");
  182. }
  183. }
  184. }
  185. @Test
  186. @Ignore("If we decide we can use common crawl file specified, we can turn this back on")
  187. public void testCyrillic() throws Exception {
  188. //TODO: move test file to framework and fix this
  189. File dir = new File("C:/somethingOrOther");
  190. File f = new File(dir, "ZMLH54SPLI76NQ7XMKVB7SMUJA2HTXTS-2.wmf");
  191. HwmfPicture wmf = new HwmfPicture(new FileInputStream(f));
  192. Charset charset = LocaleUtil.CHARSET_1252;
  193. StringBuilder sb = new StringBuilder();
  194. //this is pure hackery for specifying the font
  195. //this happens to work on this test file, but you need to
  196. //do what Graphics does by maintaining the stack, etc.!
  197. for (HwmfRecord r : wmf.getRecords()) {
  198. if (r.getWmfRecordType().equals(HwmfRecordType.createFontIndirect)) {
  199. HwmfFont font = ((HwmfText.WmfCreateFontIndirect)r).getFont();
  200. charset = (font.getCharset().getCharset() == null) ? LocaleUtil.CHARSET_1252 : font.getCharset().getCharset();
  201. }
  202. if (r.getWmfRecordType().equals(HwmfRecordType.extTextOut)) {
  203. HwmfText.WmfExtTextOut textOut = (HwmfText.WmfExtTextOut)r;
  204. sb.append(textOut.getText(charset)).append("\n");
  205. }
  206. }
  207. String txt = sb.toString();
  208. assertContains(txt, "\u041E\u0431\u0449\u043E");
  209. assertContains(txt, "\u0411\u0430\u043B\u0430\u043D\u0441");
  210. }
  211. @Test
  212. @Ignore("If we decide we can use the common crawl file attached to Bug 60677, " +
  213. "we can turn this back on")
  214. public void testShift_JIS() throws Exception {
  215. //TODO: move test file to framework and fix this
  216. File f = new File("C:/data/file8.wmf");
  217. HwmfPicture wmf = new HwmfPicture(new FileInputStream(f));
  218. Charset charset = LocaleUtil.CHARSET_1252;
  219. StringBuilder sb = new StringBuilder();
  220. //this is pure hackery for specifying the font
  221. //this happens to work on this test file, but you need to
  222. //do what Graphics does by maintaining the stack, etc.!
  223. for (HwmfRecord r : wmf.getRecords()) {
  224. if (r.getWmfRecordType().equals(HwmfRecordType.createFontIndirect)) {
  225. HwmfFont font = ((HwmfText.WmfCreateFontIndirect)r).getFont();
  226. charset = (font.getCharset().getCharset() == null) ? LocaleUtil.CHARSET_1252 : font.getCharset().getCharset();
  227. }
  228. if (r.getWmfRecordType().equals(HwmfRecordType.extTextOut)) {
  229. HwmfText.WmfExtTextOut textOut = (HwmfText.WmfExtTextOut)r;
  230. sb.append(textOut.getText(charset)).append("\n");
  231. }
  232. }
  233. String txt = sb.toString();
  234. assertContains(txt, "\u822A\u7A7A\u60C5\u5831\u696D\u52D9\u3078\u306E\uFF27\uFF29\uFF33");
  235. }
  236. }