Exploring a WMF File, (0X000900)


Porpouse

Maybe, you are looking for to understand how is stored the Image in formation in WMF File according to explanation of this Format, Microsoft has this file WindowsMetafileFormat(wmf)Specification.pdf

Limitations

This post is centered in the file that starts with 01 00 09 00 (01000900), this article can be used too with files WMF starting with 02 00 09 00 (02000900).

Obtaining One Sample of this File Type

In order to obtain this file I made one .BMP File SquareColor.bmp

SquareColor.BMP

Using Wordpad of Microsoft Windows 7 the file was inserted in one .RTF File SquareColor.rtf

SquareColor.RTF

The image is converted from the original format and stored (using text of hexadecimal representation) between this code:

{\rtf1\ansi\ansicpg1252\deff0\deflang9226{\fonttbl{\f0\fnil\fcharset0 Calibri;}}
{\*\generator Msftedit 5.41.21.2510;}\viewkind4\uc1\pard\sa200\sl240\slmult1\lang10\f0\fs22{\pict\wmetafile8\picw6773\pich6773\picwgoal3840\pichgoal3840

}\par
\pard\sa200\sl276\slmult1\par
}

SquareColor.RTF_NotepadThe File is obtained, converting the text representation of each byte in one byte and all bytes are stored in new file with .WMF extension. Here is the final .WMF file SquareColor.wmf

Now You can see this image:
SquareColor.WMFNow you can see the comparation between .WMF and .BMP

SquareColor_Comparation

Inside of 0X000900 WMF File

The file can be find in two versions in 01000900 or 02000900.

The File uses Little Endianness representation.

In Hexadecimal 01 00 represents 1 in Decimal
In Hexadecimal 00 01 represents 256 in Decimal

First Control Record: META_HEADER

The first control record contains fields detailed in the Page 116 of File Specificacion, the fields are:

Type

HexRepresentation_SquareColor_aType
The first two bytes 1(01) and 2(00) describes the type of file, in this case 00 01 that means the type is MEMORYMETAFILE, the page 40 describe the two types.

HeaderSize

HexRepresentation_SquareColor_aHeaderSize
The bytes 3(09) and 4(00) represents the size of this Control Record, in this case 00 09, 9 Words, equivalent to 18 bytes.

Version of MetaFile

The Bytes 5(00) and 6(03), are describing the version of MetaFile, for our WMF File Example the version is: 03 00 corresponding to METAVERSION300 according to Page 40 of Specification File.

HexRepresentation_SquareColorVersion

Size of File

The Bytes 7(6A), 8(40), 9(00) and 10(00) Stores the file size expressed in Words (two byte), in hexadecimal 00 00 40 6A represents 16490 Words in decimal; Expressed in bytes 2×16490 this is 32980 bytes.

HexRepresentation_SquareColorFileSize

Objects Number

The Bytes 11(00) and 12(00) Indicates the number of objects contained in the file. According to this there is not objects in the file.

HexRepresentation_SquareColor_ObjectsNumber

Largest Record

The Bytes 13(41), 14(40), 15(00) and 16(00) Says us that the largest record of contained in the file is in hexadecimal 00 00 40 41 and in bytes 32898.

HexRepresentation_SquareColor_MaxRecord

Members Number

The Bytes 17(00) and 18(00) Are not used.

HexRepresentation_SquareColor_NotUsed

Other Records

The records are stored in serial mode (one after another).
The first four bytes (two words) indicate the size of record, the following two bytes (one word) indicate the operation or function. The remaining bytes (Size in bytes less six bytes) are the function argument.

In this file we have several records, I made in Java an extraction of this information (Only is applicable to this file .wmf).

Table_FunctionsThe position of this application starts from 0, but the position of this post starts from 1; Thus, The byte 19th of this post is stored in the position 18th of this picture; and so on for the remainder.

Record 2

HexRepresentation_SquareColor_META_SETMAPMODE The bytes 19(04), 20(00), 21(00) and 22(00) tell us the size of this record is 8 bytes (4 words); the record is stored in the bytes from 19 until 26, according to byte 23(03) and byte 24(01) the  function code is 0103 that correspond to META_SETMAPMODE, and the argument is stored in the remaining 2 bytes 25(08) and 26(00) with code 0008 that correspond to MM_ANISOTROPIC.

Record 3

HexRepresentation_SquareColor_META_SETWINDOWORGThe bytes 27(05), 28(00), 29(00) and 30(00) tell us the size of this record is 10 bytes (5 words); the record is stored in the bytes from 27 until 36, according to byte 31(0B) and byte 32(02) the function code is 020B that correspond to META_SETWINDOWORG, and the argument is stored in the remaining 4 bytes 33(00), 34(00), 35(00) and 36(00) . According to this function the first two bytes represents horizontal position (0 in this case) and the last two bytes represents the vertical position (0 in this case), in this manner the position is 0,0.

Record 4

HexRepresentation_SquareColor_META_SETWINDOWEXTThe bytes 37(05), 38(00), 39(00) and 40(00) represents the size of this record is 10 bytes (5 words); the record is stored in the bytes from 37 until 46, according to byte 41(0C) and byte 42(02) the function code is 020C that correspond to META_SETWINDOWEXT, and the argument is stored in the remaining 4 bytes 43(00), 44(01), 45(00) and 46(01) . According to this function the first two bytes represents horizontal size (256 in this case) and the last two bytes represents the vertical size (256 in this case), in this manner the dimension is 256×256.

Record 5

HexRepresentation_SquareColor_META_SAVEDCNow we have a record that only contains, the size 6 bytes (3 words) represented by the bytes 47(03), 48(00), 49(00) and 50(00) and the function code 001E stored in the bytes 51(1E) and 52(00) that is META_SAVEDC.

Record 6

HexRepresentation_SquareColor_META_SETSTRETCHBLTMODEThe Record 6 has a size 8 bytes, stored from the byte 53 until the byte 60, the function code is 0107 representing META_SETSTRETCHBLTMODE and the argument is 0004 equivalent HALFTONE.

Record 7

HexRepresentation_SquareColor_META_SETSTRETCHBLTMODE_2

The record 7 is similar to the record 6, with the difference that is stored from the bytes 61 until the byte 68.

Record 8

HexRepresentation_SquareColor_META_DIBSTRETCHBLT

Maybe is the record most important of this file.

The size is 32898 bytes according to the bytes 69(41), 70(40), 71(00) and 72(00).
The function code from byte 73(41) and byte 74(0B) is 0B41 that means META_DIBSTRETCHBLT following the page 109 of Specification File we have more arguments like this:
HexRepresentation_SquareColor_META_DIBSTRETCHBLT_SRCCOPY
Raster Operation is stored in bytes 75(20), 76(00), 77(CC) and 78(00) is 00CC0020 equivalent to SRCCOPY can be verified in the page 71.
SrcHeight is stored in the bytes 79(00) and 80(01) is 0100 equivalent to 256.
SrcWidth is stored in the bytes 81(00) and 82(01) is 0100 equivalent to 256.
YSrc is stored in the bytes 83(00) and 84(00) is 0000 equivalent to 0.
XSrc is stored in the bytes 85(00) and 86(00) is 0000 equivalent to 0.
DestHeight is stored in the bytes 87(00) and 88(01) is 0100 equivalent to 256.
DestWidth is stored in the bytes 89(00) and 90(01) is 0100 equivalent to 256.
YDest is stored in the bytes 91(00) and 92(00) is 0000 equivalent to 0.
XDest is stored in the bytes 93(00) and 94(00) is 0000 equivalent to 0.

The Record contains a DIB (Device Independent Bitmap) described in the page 92 with BitmapInfoHeader described in the page 80, like:

HexRepresentation_SquareColor_META_DIBSTRETCHBLT_DIB
HeaderSize is stored in the bytes 95(28), 96(00), 97(00) and 98(00) is 00000028 equivalent to 40 bytes.
Width is stored in the bytes 99(00), 100(01), 101(00) and 102(00) is 00000100 equivalent to 256.
Height is stored in the bytes 103(00), 104(01), 105(00) and 106(00) is 00000100 equivalent to 256.
Planes is stored in the bytes 107(01) and 108(00) 0001 equivalent to 1, Page 81.
BitCount is stored in the bytes 109(04) and 110(00) 0004 equivalent to BI_BITCOUNT_2, Page 25.
Compression is stored in the bytes 111(00), 112(01), 113(00) and 114(00) is 00000000 equivalent to BI_RGB, Page 29.
ImageSize is stored in the bytes 115(00), 116(01), 117(00) and 118(00) is 00000000 This may be set to 0 for BI_RGB, Page 81.
XPelsPerMeter is stored in the bytes 119(00), 120(01), 121(00) and 122(00) is 00000000.
YPelsPerMeter is stored in the bytes 123(00), 124(01), 125(00) and 126(00) is 00000000.
ColorUsed is stored in the bytes 127(00), 128(01), 129(00) and 130(00) is 00000000, the bitmap uses the maximum number of colors.
ColorImportant is stored in the bytes 131(00), 132(01), 133(00) and 134(00) is 00000000, where all colors are required.
You can see that this example contains a field named ColorUsage stored in the bytes 135(00), 136(00), 137(00) and 138(00), equivalent to DIB_RGB_COLORS, Page 29.
The aData Is the last field of this record, consist in array of bytes(with variable size) defining the actual bitmap bits.

Record 9

HexRepresentation_SquareColor_META_RESTOREDC

In this case, the record 9 is located just before the last record, this penultimate record has a size of 8 bytes (4 words), the funcion code is 0127 refering to META_RESTOREDC and like the value of its argument named nSavedDC is FF FF equivalent to negative number, nSavedDC represents an instance relative to the current state.

Last Control Record: META_EOF

HexRepresentation_SquareColor_META_EOF

The last record is incated with a record of the last 6 bytes (3 words), as you can see the function code in this case is stored in the last two bytes with penultimate byte (00) and last byte (00) this is 0000 belongs to META_EOF.

Modifications

Now, I post a file example with some modifications that allow us, to view the behaviour with this changes.
The size of the original image is 256x256, now the product of the vertical size with the horizontal size is the total image size equal to 65536, this size was stablished because changing original vertical and horizontal symmetrically this total image size can be preserved with the same value. Example of this is 128x512 or 512x128, the changes can be made following the Height and Width dimension stored in the original file and detailed in this post.

Just like that we was reviewing the post the 256 number is represented in hexadecimal like 100, if 2 bytes are used with Little Endianness representation will be 1(00) and the 2(01): 00 01; if 4 bytes are used in this case the representation will be 1(00), 2(01), 3(00) and 4(00): 00 01 00 00.
The decimal number 128 is represented in hexadecimal like 80, if 2 bytes are used with Little Endianness representation will be 1(80) and the 2(00): 80 00; if 4 bytes are used in this case the representation will be 1(80), 2(00), 3(00) and 4(00): 80 00 00 00.
The decimal number 512 is represented in hexadecimal like 200, if 2 bytes are used with Little Endianness representation will be 1(00) and the 2(02): 00 02; if 4 bytes are used in this case the representation will be 1(00), 2(02), 3(00) and 4(00): 00 02 00 00.

Now just we need change one 256 by 128 y the other 256 by 512, according to which dimension we want to establish.

Comparation_SquareColor

The result for Height 512, Width 128 is:

SquareColorH
SquareColorH.WMF

The result for Height 128, Width 512 is:

SquareColorV
SquareColorV.WMF

Now if you have comments, please let me know.

Anuncios

Acerca de joseluisbz

Hasta ahora, espero actualizarlo después, ahora no.
Esta entrada fue publicada en Dimension, Image, Size y etiquetada , , , , , , , , , , , , . Guarda el enlace permanente.

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión /  Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión /  Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión /  Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión /  Cambiar )

Conectando a %s