WMF1 parses .wmf files. It checks for a placeable header, reads the metafile header, and then the metarecords until it finds the EOF record (or the EOF of the file).
C:\ece538\WMF>java WMF1 hex1.wmf metafile type 1 header size: 9 Version: 300 size: 54 number of objects 2 max record size (16-bit words) 12 unused (should be zero) 0 obj size type 1 8 2fa 2 4 12d 3 7 2fc 4 4 12c 5 7 41b 6 12 521 7 3 0 54 words including header
C:\ece538\WMF>java WMF1 example1.wmf placeable header 9ac6cdd7 handle 0 bounding box 0 6680afd test subarray 668 1640 Inch: 576 Reserved: 0 Checksum: 59c4 metafile type 1 header size: 9 Version: 300 size: 199 number of objects 4 max record size (16-bit words) 12 unused (should be zero) 0 obj size type 1 4 103 2 5 20b 3 5 20c 4 3 1e 5 3 1e 6 7 416 7 8 2fa 8 4 12d 9 7 2fc 10 4 12d 11 12 325 12 8 2fa 13 4 12d 14 7 2fc 15 4 12d 16 4 127 17 4 1f0 18 8 2fa 19 4 12d 20 4 12d 21 8 325 22 4 12d 23 4 12d 24 4 1f0 25 3 1e 26 7 416 27 8 2fa 28 4 12d 29 4 12d 30 12 324 31 4 12d 32 4 12d 33 4 127 34 4 1f0 35 4 127 36 3 0 199 words including header
WMF1.java
import java.io.*; import java.util.Arrays; public class WMF1 { public static int get32(byte[] b) { int v; v = (b[3]&0xff)<<24; v += (b[2]&0xff)<<16; v += (b[1]&0xff)<<8; v += (b[0]&0xff); return v; } public static int get16(byte[] b) { int v; v = (b[1]&0xff)<<8; v += (b[0]&0xff); return v; } public static void readFile(String filename) { try(BufferedInputStream in = new BufferedInputStream(new FileInputStream(filename))) { byte[] b = new byte[64]; byte[] c; int eof, count, n, type; int v1,v2; in.read(b,0,4); type = get32(b); if (type==0x9AC6CDD7) { // 11 words System.out.format("placeable header %4x\n",type); in.read(b,0,2); System.out.format("handle %2x\n",get16(b)); in.read(b,0,4); v1 = get32(b); in.read(b,0,4); v2 = get32(b); System.out.format("bounding box %4x %4x\n",v1,v2); c = Arrays.copyOfRange(b,0,2); v1 = get16(c); c = Arrays.copyOfRange(b,2,4); v2 = get16(c); System.out.format("test subarray %2x %d\n",v2,v2); in.read(b,0,2); System.out.format("Inch: %d\n",get16(b)); in.read(b,0,4); System.out.format("Reserved: %x\n",get32(b)); in.read(b,0,2); System.out.format("Checksum: %x\n\n",get16(b)); in.read(b,0,4); } // 9 words c = Arrays.copyOfRange(b,0,2); System.out.format("metafile type %2x\n",get16(c)); c = Arrays.copyOfRange(b,2,4); System.out.format("header size: %d\n",get16(c)); in.read(b,0,2); System.out.format("Version: %x\n",get16(b)); in.read(b,0,4); System.out.format("size: %d\n",get32(b)); in.read(b,0,2); System.out.format("number of objects %d\n",get16(b)); in.read(b,0,4); System.out.format("max record size (16-bit words) %d\n",get32(b)); in.read(b,0,2); System.out.format("unused (should be zero) %x\n",get16(b)); count = 0; System.out.println("\nobj size type"); for (int obj=1; obj<1024; obj++) { eof = in.read(b,0,4); if (eof<0) break; n = get32(b); count = count + n; in.read(b,0,2); type = get16(b); if (n>3) in.read(b,0,2*(n-3)); System.out.format("%3d %4d %4x\n",obj,n,type); } System.out.format("\n %d words including header\n",count+9); // META_SAVEDC = 0x001E // 12d - META_SELECTOBJECT // 324 - META_POLYGON+ // 325 - META_POLYLINE // META_INTERSECTCLIPRECT = 0x0416 // META_DELETEOBJECT = 0x01f0 // META_CREATEPENINDIRECT = 0x02FA // META_CREATEBRUSHINDIRECT = 0x02FC, in.close(); } catch(Exception e) { System.err.println(e); } } public static void main(String [] args) { String filename = "example1.wmf"; if (args.length>0) filename = args[0]; readFile(filename); } }
Maintained by John Loomis, updated Sat Mar 25 20:57:42 2017