Discussion:
Creating and displaying EMZ files
(too old to reply)
Richard
2003-10-30 16:17:05 UTC
Permalink
I've heard that emz files are compressed emf files. They're certainly
a _lot_ smaller. My application generates and displays _large_ emf
files. I'd really like to migrate to emz if possible.

Searching for emz on MSDN just hits office apps. A previous post says
they're lha compressed. Is that true? No other header information in
the file?

Now for the difficult part. It looks like office decompresses the emz
into the temp directory and then renders the emf. I'd much rather
enumerate the emf stream directly from the emz since my emfs are so
big. Is there any way to do this?

I was hoping to use some combination of
EnumEnhMetaFile/PlayEnhMetaFileRecord but these functions require an
existing metafile handle.

Thanks for any thoughts,
Richard.
John Hornick [MSFT]
2003-10-30 17:41:47 UTC
Permalink
Hi,

I'm unaware of any inherent support for that format in the GDI APIs,
and I don't see any Microsoft documentation around this format.

Thanks,
- John
Microsoft Developer Support
This posting is provided "AS IS" with no warranties, and confers no rights.
Visit http://www.microsoft.com/security for current information on security.
Post by Richard
I've heard that emz files are compressed emf files. They're certainly
a _lot_ smaller. My application generates and displays _large_ emf
files. I'd really like to migrate to emz if possible.
Searching for emz on MSDN just hits office apps. A previous post says
they're lha compressed. Is that true? No other header information in
the file?
Now for the difficult part. It looks like office decompresses the emz
into the temp directory and then renders the emf. I'd much rather
enumerate the emf stream directly from the emz since my emfs are so
big. Is there any way to do this?
I was hoping to use some combination of
EnumEnhMetaFile/PlayEnhMetaFileRecord but these functions require an
existing metafile handle.
Richard
2003-10-31 03:35:37 UTC
Permalink
I wasn't really expecting a CreateEMZMetaFile() function. I don't
mind decompressing the file myself. Is there any way to spoof
EnumEnhMetaFile/PlayEnhMetaFileRecord with synthesized emf records?
Perhaps I could get in under GetEnhMetafile?
Thanks,
Richard.
Post by John Hornick [MSFT]
Hi,
I'm unaware of any inherent support for that format in the GDI APIs,
and I don't see any Microsoft documentation around this format.
Thanks,
- John
Microsoft Developer Support
This posting is provided "AS IS" with no warranties, and confers no rights.
Visit http://www.microsoft.com/security for current information on security.
Post by Richard
I've heard that emz files are compressed emf files. They're certainly
a _lot_ smaller. My application generates and displays _large_ emf
files. I'd really like to migrate to emz if possible.
Searching for emz on MSDN just hits office apps. A previous post says
they're lha compressed. Is that true? No other header information in
the file?
Now for the difficult part. It looks like office decompresses the emz
into the temp directory and then renders the emf. I'd much rather
enumerate the emf stream directly from the emz since my emfs are so
big. Is there any way to do this?
I was hoping to use some combination of
EnumEnhMetaFile/PlayEnhMetaFileRecord but these functions require an
existing metafile handle.
vipin
2003-10-31 06:18:01 UTC
Permalink
This post might be inappropriate. Click to display it.
Richard
2003-10-31 15:41:38 UTC
Permalink
Example files sent via email:
file size zipped size
test.emz 664 664
test.emf 1264 646
test_pic.emz 265,051 264,569
test_pic.emf 483,468 266,326

If you look at the files it's pretty clear that the emz is just a
compressed emf. I suspect if we pass the emz files unchanged to a lha
decoder as suggested by Fen Yuan earlier we'd end up with an emf file.

I've heard that Visio can save emz files directly but I don't have
that installed. To create an emz from Word 2002:
Insert->Picure->From File... (select an emf)
File->Save As... select Web Page as type.
You will see a <filename>_files folder int the same folder as the htm
file.
There will be an emz file of your original emf in this folder.

If you open the htm file in IE and monitor your user/local
settings/temp directory you will see a tmp file appear that is the
same size as the original emf. Copy the tmp file and change it's
extension to .emf and viola - it's your original emf.

What interests me is some cunning way of rendering these emz files
without decompressing to a temp file. Worst case I could write my own
emz enumerator but I'd rather not do that.

Richard.
Post by vipin
Its interesting thing to get the hacking trail going.
Can you send me an emf and the corresponding emz or
atleast tell me how to create emz file from emf file using
office application? send me the files to
vipin.aravind at wipro.com
I very much suspect emz if such a format exists would be
compressing bitmaps in emf using a lossless RLE, whatelse
could be. Much would be clear once we look at the bits of
those files. So please send them across.
vipin
-----Original Message-----
I wasn't really expecting a CreateEMZMetaFile()
function. I don't
mind decompressing the file myself. Is there any way to
spoof
EnumEnhMetaFile/PlayEnhMetaFileRecord with synthesized
emf records?
Perhaps I could get in under GetEnhMetafile?
Thanks,
Richard.
Post by John Hornick [MSFT]
Hi,
I'm unaware of any inherent support for that format in
the GDI APIs,
Post by John Hornick [MSFT]
and I don't see any Microsoft documentation around this
format.
Post by John Hornick [MSFT]
Thanks,
- John
Microsoft Developer Support
This posting is provided "AS IS" with no warranties,
and confers no rights.
Post by John Hornick [MSFT]
Visit http://www.microsoft.com/security for current
information on security.
Post by John Hornick [MSFT]
Post by Richard
I've heard that emz files are compressed emf files.
They're certainly
Post by John Hornick [MSFT]
Post by Richard
a _lot_ smaller. My application generates and
displays _large_ emf
Post by John Hornick [MSFT]
Post by Richard
files. I'd really like to migrate to emz if possible.
Searching for emz on MSDN just hits office apps. A
previous post says
Post by John Hornick [MSFT]
Post by Richard
they're lha compressed. Is that true? No other
header information in
Post by John Hornick [MSFT]
Post by Richard
the file?
Now for the difficult part. It looks like office
decompresses the emz
Post by John Hornick [MSFT]
Post by Richard
into the temp directory and then renders the emf.
I'd much rather
Post by John Hornick [MSFT]
Post by Richard
enumerate the emf stream directly from the emz since
my emfs are so
Post by John Hornick [MSFT]
Post by Richard
big. Is there any way to do this?
I was hoping to use some combination of
EnumEnhMetaFile/PlayEnhMetaFileRecord but these
functions require an
Post by John Hornick [MSFT]
Post by Richard
existing metafile handle.
.
vipin
2003-11-01 10:21:45 UTC
Permalink
I was able to use winzip to decompress your emz files to
emf files and view it.This has nothing to do with
GDI.There is no support in GDI.
vipin
-----Original Message-----
file size zipped size
test.emz 664 664
test.emf 1264 646
test_pic.emz 265,051 264,569
test_pic.emf 483,468 266,326
If you look at the files it's pretty clear that the emz
is just a
compressed emf. I suspect if we pass the emz files
unchanged to a lha
decoder as suggested by Fen Yuan earlier we'd end up with
an emf file.
I've heard that Visio can save emz files directly but I
don't have
Insert->Picure->From File... (select an emf)
File->Save As... select Web Page as type.
You will see a <filename>_files folder int the same
folder as the htm
file.
There will be an emz file of your original emf in this
folder.
If you open the htm file in IE and monitor your user/local
settings/temp directory you will see a tmp file appear
that is the
same size as the original emf. Copy the tmp file and
change it's
extension to .emf and viola - it's your original emf.
What interests me is some cunning way of rendering these
emz files
without decompressing to a temp file. Worst case I could
write my own
emz enumerator but I'd rather not do that.
Richard.
Post by vipin
Its interesting thing to get the hacking trail going.
Can you send me an emf and the corresponding emz or
atleast tell me how to create emz file from emf file
using
Post by vipin
office application? send me the files to
vipin.aravind at wipro.com
I very much suspect emz if such a format exists would
be
Post by vipin
compressing bitmaps in emf using a lossless RLE,
whatelse
Post by vipin
could be. Much would be clear once we look at the bits
of
Post by vipin
those files. So please send them across.
vipin
-----Original Message-----
I wasn't really expecting a CreateEMZMetaFile()
function. I don't
mind decompressing the file myself. Is there any way
to
Post by vipin
spoof
EnumEnhMetaFile/PlayEnhMetaFileRecord with synthesized
emf records?
Perhaps I could get in under GetEnhMetafile?
Thanks,
Richard.
Post by John Hornick [MSFT]
Hi,
I'm unaware of any inherent support for that format
in
Post by vipin
the GDI APIs,
Post by John Hornick [MSFT]
and I don't see any Microsoft documentation around
this
Post by vipin
format.
Post by John Hornick [MSFT]
Thanks,
- John
Microsoft Developer Support
This posting is provided "AS IS" with no warranties,
and confers no rights.
Post by John Hornick [MSFT]
Visit http://www.microsoft.com/security for current
information on security.
Post by John Hornick [MSFT]
Post by Richard
I've heard that emz files are compressed emf
files.
Post by vipin
They're certainly
Post by John Hornick [MSFT]
Post by Richard
a _lot_ smaller. My application generates and
displays _large_ emf
Post by John Hornick [MSFT]
Post by Richard
files. I'd really like to migrate to emz if
possible.
Post by vipin
Post by John Hornick [MSFT]
Post by Richard
Searching for emz on MSDN just hits office apps.
A
Post by vipin
previous post says
Post by John Hornick [MSFT]
Post by Richard
they're lha compressed. Is that true? No other
header information in
Post by John Hornick [MSFT]
Post by Richard
the file?
Now for the difficult part. It looks like office
decompresses the emz
Post by John Hornick [MSFT]
Post by Richard
into the temp directory and then renders the emf.
I'd much rather
Post by John Hornick [MSFT]
Post by Richard
enumerate the emf stream directly from the emz
since
Post by vipin
my emfs are so
Post by John Hornick [MSFT]
Post by Richard
big. Is there any way to do this?
I was hoping to use some combination of
EnumEnhMetaFile/PlayEnhMetaFileRecord but these
functions require an
Post by John Hornick [MSFT]
Post by Richard
existing metafile handle.
.
.
Jonathan Wilson
2003-11-01 11:27:11 UTC
Permalink
ok, after doing some testing, I found that a *.emz file is a compressed EMF.
It is compressed with the same compression as the ZLIB compression library
uses.
You should be able to read & write these files with the ZLIB compression
library.
Go to http://www.gzip.org/zlib/ to get the zlib library.

Its well known and is used in many many programs (although I have
personally never used it). Just make sure you comply with the licence
aggrement.

The same compression algorihim is used for the ZIP format and the GZIP format.
John Hornick [MSFT]
2003-10-31 15:11:23 UTC
Permalink
Hi,

Presuming you can decode the compressed records, it seems you should
be able to loop through them and PlayEnhMetaFile() on each one. EMF
records include, right in their headers, a record-size parameter - so
looping through them is fairly easy.

Thanks,
- John
Microsoft Developer Support
This posting is provided "AS IS" with no warranties, and confers no rights.
Visit http://www.microsoft.com/security for current information on security.
Post by Richard
I wasn't really expecting a CreateEMZMetaFile() function. I don't
mind decompressing the file myself. Is there any way to spoof
EnumEnhMetaFile/PlayEnhMetaFileRecord with synthesized emf records?
Perhaps I could get in under GetEnhMetafile?
Richard
2003-10-31 18:25:10 UTC
Permalink
You're right of course. I'd mistakenly assumed that nObj in
EnhMetaFilePro()
was the number of handles used. Debugging the callback it looks like
it's the size of the handle table and that handles are added at the
first null value in the table. I'll try manually enumerating a emf
file first before I get into the compression part.

Is there no information you can share about the emz file before I
start looking into it? The fact that Viseo, Word etc supports it
suggests that MS has some interest in the format.

Thanks,
Richard.
Post by John Hornick [MSFT]
Hi,
Presuming you can decode the compressed records, it seems you should
be able to loop through them and PlayEnhMetaFile() on each one. EMF
records include, right in their headers, a record-size parameter - so
looping through them is fairly easy.
Thanks,
- John
Microsoft Developer Support
This posting is provided "AS IS" with no warranties, and confers no rights.
Visit http://www.microsoft.com/security for current information on security.
Post by Richard
I wasn't really expecting a CreateEMZMetaFile() function. I don't
mind decompressing the file myself. Is there any way to spoof
EnumEnhMetaFile/PlayEnhMetaFileRecord with synthesized emf records?
Perhaps I could get in under GetEnhMetafile?
John Hornick [MSFT]
2003-10-31 19:02:06 UTC
Permalink
Hi,
Post by Richard
Is there no information you can share about the emz file before I
start looking into it? The fact that Viseo, Word etc supports it
suggests that MS has some interest in the format.
You might ask on an Office newsgroup. I work with GDI and GDI+, and
I've seen nothing in either which suggests support for that format.

Thanks,
- John
Microsoft Developer Support
This posting is provided "AS IS" with no warranties, and confers no rights.
Visit http://www.microsoft.com/security for current information on security.
Richard
2003-11-01 03:47:31 UTC
Permalink
Thanks John, will try microsoft.public.office.developer.officedev.other.
Richard.
Post by John Hornick [MSFT]
Hi,
Post by Richard
Is there no information you can share about the emz file before I
start looking into it? The fact that Viseo, Word etc supports it
suggests that MS has some interest in the format.
You might ask on an Office newsgroup. I work with GDI and GDI+, and
I've seen nothing in either which suggests support for that format.
Thanks,
- John
Microsoft Developer Support
This posting is provided "AS IS" with no warranties, and confers no rights.
Visit http://www.microsoft.com/security for current information on securi
Richard
2003-11-05 18:26:24 UTC
Permalink
Just to finish the thread:

EMZ files are gzipped EMF files. It's easy to convert a file between
the formats using zlib's gzopen/gzread/gzwrite/gzclose funtions.

It's a bit trickier to play an EMZ file without decompressing it
first. I had to create a bogus emf in memory and then spoof the
enumerate function. My code ended up looking something like this
(with error checking of course).

EnumEmzMetaFile(hdc, filename, lpRect)
{
gzFile ifile;
ENHMETAHEADER EmfHeader;
ifile = gzopen(strFilename, "rb");
gzread(ifile, &EmfHeader, sizeof(EmfHeader));
gzseek(ifile, EmfHeader.nSize);

EmfHeader.nBytes = EmfHeader.nSize = sizeof(EmfHeader);
EmfHeader.nDescription = 0;
EmfHeader.offDescription = EmfHeader.nSize;
EmfHeader.nRecords = 1;

HENHMETAFILE bogusEMF = SetEnhMetaFileBits(sizeof(EmfHeader),
(CONST BYTE*)&EmfHeader);

::EnumEnhMetaFile(hdc, bogusEMF, BogusEmfCallback, ifile, lpRect);

gzclose(ifile);
}

static int CALLBACK BogusEmfCallback(hDC,lpHTable,lpEMFR,nObj,lpData )
{
PlayEnhMetaFileRecord( hDC, lpHTable, lpEMFR, nObj );

gzFile ifile = (gzFile) lpData;

DWORD nCmdBufferSize = 1000;
char *cmdBuffer = (char*)calloc(nCmdBufferSize, 1);

for (DWORD nBytesPending=gzread(ifile,cmdBuffer,nCmdBufferSize);
sizeof(EMR) <= nBytesPending;
nBytesPending += gzread(ifile, &cmdBuffer[nBytesPending],
nCmdBufferSize-nBytesPending))
{

char *cmdPtr = cmdBuffer;
ENHMETARECORD *command = (ENHMETARECORD *)cmdPtr;
while((command->nSize <= nBytesPending) &&
(nBytesPending > sizeof(EMR)))
{
PlayEnhMetaFileRecord( hDC, lpHTable, command, nObj );
nBytesPending -= command->nSize;
cmdPtr += command->nSize;
command = (ENHMETARECORD *)cmdPtr;
}
if (nBytesPending) {
if ((nBytesPending > sizeof(EMR)) &&
(command->nSize > nCmdBufferSize))
{
char *cmdBufferTmp = (char*)malloc(command->nSize);
if (cmdBufferTmp) {
memcpy(cmdBufferTmp, cmdPtr, nBytesPending);
nCmdBufferSize = command->nSize;
free(cmdBuffer);
cmdBuffer = cmdBufferTmp;
} else {
gzseek(ifile, command->nSize-nBytesPending, SEEK_CUR);
nBytesPending = 0;
}
} else {
memcpy(cmdBuffer, command, nBytesPending); // risky
}
}
}
if (cmdBuffer) free(cmdBuffer);
return 1;
}
Post by Richard
Thanks John, will try microsoft.public.office.developer.officedev.other.
Richard.
Post by John Hornick [MSFT]
Hi,
Post by Richard
Is there no information you can share about the emz file before I
start looking into it? The fact that Viseo, Word etc supports it
suggests that MS has some interest in the format.
You might ask on an Office newsgroup. I work with GDI and GDI+, and
I've seen nothing in either which suggests support for that format.
Thanks,
- John
Microsoft Developer Support
This posting is provided "AS IS" with no warranties, and confers no rights.
Visit http://www.microsoft.com/security for current information on securi
Loading...