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.javaimport 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