root/ImageMagick/trunk/coders/emf.c

Revision 603, 21.5 KB (checked in by cristy, 4 days ago)
Line 
1/*
2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3%                                                                             %
4%                                                                             %
5%                                                                             %
6%                            EEEEE  M   M  FFFFF                              %
7%                            E      MM MM  F                                  %
8%                            EEE    M M M  FFF                                %
9%                            E      M   M  F                                  %
10%                            EEEEE  M   M  F                                  %
11%                                                                             %
12%                                                                             %
13%                  Read Windows Enahanced Metafile Format                     %
14%                                                                             %
15%                              Software Design                                %
16%                              Bill Radcliffe                                 %
17%                                   2001                                      %
18%                                                                             %
19%  Copyright 1999-2009 ImageMagick Studio LLC, a non-profit organization      %
20%  dedicated to making software imaging solutions freely available.           %
21%                                                                             %
22%  You may not use this file except in compliance with the License.  You may  %
23%  obtain a copy of the License at                                            %
24%                                                                             %
25%    http://www.imagemagick.org/script/license.php                            %
26%                                                                             %
27%  Unless required by applicable law or agreed to in writing, software        %
28%  distributed under the License is distributed on an "AS IS" BASIS,          %
29%  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   %
30%  See the License for the specific language governing permissions and        %
31%  limitations under the License.                                             %
32%                                                                             %
33%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
34*/
35
36/*
37 * Include declarations.
38 */
39
40#include "magick/studio.h"
41#if defined(MAGICKCORE_WINGDI32_DELEGATE)
42if defined(__CYGWIN__)
43#    include <windows.h>
44else
45     /* All MinGW needs ... */
46#    include <wingdi.h>
47endif
48#endif
49
50#include "magick/blob.h"
51#include "magick/blob-private.h"
52#include "magick/cache.h"
53#include "magick/exception.h"
54#include "magick/exception-private.h"
55#include "magick/geometry.h"
56#include "magick/image.h"
57#include "magick/image-private.h"
58#include "magick/list.h"
59#include "magick/magick.h"
60#include "magick/memory_.h"
61#include "magick/quantum-private.h"
62#include "magick/static.h"
63#include "magick/string_.h"
64#include "magick/module.h"
65
66/*
67%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
68%                                                                             %
69%                                                                             %
70%                                                                             %
71%   I s E F M                                                                 %
72%                                                                             %
73%                                                                             %
74%                                                                             %
75%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
76%
77%  IsEMF() returns MagickTrue if the image format type, identified by the
78%  magick string, is a Microsoft Windows Enhanced MetaFile (EMF) file.
79%
80%  The format of the ReadEMFImage method is:
81%
82%      MagickBooleanType IsEMF(const unsigned char *magick,const size_t length)
83%
84%  A description of each parameter follows:
85%
86%    o magick: compare image format pattern against these bytes.
87%
88%    o length: Specifies the length of the magick string.
89%
90*/
91static MagickBooleanType IsEMF(const unsigned char *magick,const size_t length)
92{
93  if (length < 48)
94    return(MagickFalse);
95  if (memcmp(magick+40,"\040\105\115\106\000\000\001\000",8) == 0)
96    return(MagickTrue);
97  return(MagickFalse);
98}
99
100/*
101%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
102%                                                                             %
103%                                                                             %
104%                                                                             %
105%   I s W M F                                                                 %
106%                                                                             %
107%                                                                             %
108%                                                                             %
109%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
110%
111%  IsWMF() returns MagickTrue if the image format type, identified by the
112%  magick string, is a Windows MetaFile (WMF) file.
113%
114%  The format of the ReadEMFImage method is:
115%
116%      MagickBooleanType IsEMF(const unsigned char *magick,const size_t length)
117%
118%  A description of each parameter follows:
119%
120%    o magick: compare image format pattern against these bytes.
121%
122%    o length: Specifies the length of the magick string.
123%
124*/
125static MagickBooleanType IsWMF(const unsigned char *magick,const size_t length)
126{
127  if (length < 4)
128    return(MagickFalse);
129  if (memcmp(magick,"\327\315\306\232",4) == 0)
130    return(MagickTrue);
131  if (memcmp(magick,"\001\000\011\000",4) == 0)
132    return(MagickTrue);
133  return(MagickFalse);
134}
135
136/*
137%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
138%                                                                             %
139%                                                                             %
140%                                                                             %
141%  R e a d E M F I m a g e                                                    %
142%                                                                             %
143%                                                                             %
144%                                                                             %
145%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
146%
147%  ReadEMFImage() reads an Microsoft Windows Enhanced MetaFile (EMF) or
148%  Windows MetaFile (WMF) file using the Windows API and returns it.  It
149%  allocates the memory necessary for the new Image structure and returns a
150%  pointer to the new image.
151%
152%  The format of the ReadEMFImage method is:
153%
154%      Image *ReadEMFImage(const ImageInfo *image_info,
155%        ExceptionInfo *exception)
156%
157%  A description of each parameter follows:
158%
159%    o image_info: the image info..
160%
161%    o exception: return any errors or warnings in this structure.
162%
163*/
164
165#if defined(MAGICKCORE_HAVE__WFOPEN)
166static size_t UTF8ToUTF16(const unsigned char *utf8,wchar_t *utf16)
167{
168  register const unsigned char
169    *p;
170
171  if (utf16 != (wchar_t *) NULL)
172    {
173      register wchar_t
174        *q;
175
176      wchar_t
177        c;
178
179      /*
180        Convert UTF-8 to UTF-16.
181      */
182      q=utf16;
183      for (p=utf8; *p != '\0'; p++)
184      {
185        if ((*p & 0x80) == 0)
186          *q=(*p);
187        else
188          if ((*p & 0xE0) == 0xC0)
189            {
190              c=(*p);
191              *q=(c & 0x1F) << 6;
192              p++;
193              if ((*p & 0xC0) != 0x80)
194                return(0);
195              *q|=(*p & 0x3F);
196            }
197          else
198            if ((*p & 0xF0) == 0xE0)
199              {
200                c=(*p);
201                *q=c << 12;
202                p++;
203                if ((*p & 0xC0) != 0x80)
204                  return(0);
205                c=(*p);
206                *q|=(c & 0x3F) << 6;
207                p++;
208                if ((*p & 0xC0) != 0x80)
209                  return(0);
210                *q|=(*p & 0x3F);
211              }
212            else
213              return(0);
214        q++;
215      }
216      *q++='\0';
217      return(q-utf16);
218    }
219  /*
220    Compute UTF-16 string length.
221  */
222  for (p=utf8; *p != '\0'; p++)
223  {
224    if ((*p & 0x80) == 0)
225      ;
226    else
227      if ((*p & 0xE0) == 0xC0)
228        {
229          p++;
230          if ((*p & 0xC0) != 0x80)
231            return(0);
232        }
233      else
234        if ((*p & 0xF0) == 0xE0)
235          {
236            p++;
237            if ((*p & 0xC0) != 0x80)
238              return(0);
239            p++;
240            if ((*p & 0xC0) != 0x80)
241              return(0);
242         }
243       else
244         return(0);
245  }
246  return(p-utf8);
247}
248
249static wchar_t *ConvertUTF8ToUTF16(const unsigned char *source)
250{
251  size_t
252    length;
253
254  wchar_t
255    *utf16;
256
257  length=UTF8ToUTF16(source,(wchar_t *) NULL);
258  if (length == 0)
259    {
260      register long
261        i;
262
263      /*
264        Not UTF-8, just copy.
265      */
266      length=strlen(source);
267      utf16=(wchar_t *) AcquireQuantumMemory(length+1,sizeof(*utf16));
268      if (utf16 == (wchar_t *) NULL)
269        return((wchar_t *) NULL);
270      for (i=0; i <= (long) length; i++)
271        utf16[i]=source[i];
272      return(utf16);
273    }
274  utf16=(wchar_t *) AcquireQuantumMemory(length+1,sizeof(*utf16));
275  if (utf16 == (wchar_t *) NULL)
276    return((wchar_t *) NULL);
277  length=UTF8ToUTF16(source,utf16);
278  return(utf16);
279}
280#endif
281
282/*
283  This method reads either an enhanced metafile, a regular 16bit Windows
284  metafile, or an Aldus Placeable metafile and converts it into an enhanced
285  metafile.  Width and height are returned in .01mm units.
286*/
287#if defined(MAGICKCORE_WINGDI32_DELEGATE)
288static HENHMETAFILE ReadEnhMetaFile(const char *path,long *width,
289  long *height)
290{
291#pragma pack( push, 2 )
292  typedef struct
293  {
294    DWORD dwKey;
295    WORD hmf;
296    SMALL_RECT bbox;
297    WORD wInch;
298    DWORD dwReserved;
299    WORD wCheckSum;
300  } APMHEADER, *PAPMHEADER;
301#pragma pack( pop )
302
303  DWORD
304    dwSize;
305
306  ENHMETAHEADER
307    emfh;
308
309  HANDLE
310    hFile;
311
312  HDC
313    hDC;
314
315  HENHMETAFILE
316    hTemp;
317
318  LPBYTE
319    pBits;
320
321  METAFILEPICT
322    mp;
323
324  HMETAFILE
325    hOld;
326
327  *width=512;
328  *height=512;
329  hTemp=GetEnhMetaFile(path);
330#if defined(MAGICKCORE_HAVE__WFOPEN)
331  if (hTemp == (HENHMETAFILE) NULL)
332    {
333      wchar_t
334        *unicode_path;
335
336      unicode_path=ConvertUTF8ToUTF16(path);
337      if (unicode_path != (wchar_t *) NULL)
338        {
339          hTemp=GetEnhMetaFileW(unicode_path);
340          unicode_path=(wchar_t *) RelinquishMagickMemory(unicode_path);
341        }
342    }
343#endif
344  if (hTemp != (HENHMETAFILE) NULL)
345    {
346      /*
347        Enhanced metafile.
348      */
349      GetEnhMetaFileHeader(hTemp,sizeof(ENHMETAHEADER),&emfh);
350      *width=emfh.rclFrame.right-emfh.rclFrame.left;
351      *height=emfh.rclFrame.bottom-emfh.rclFrame.top;
352      return(hTemp);
353    }
354  hOld=GetMetaFile(path);
355  if (hOld != (HMETAFILE) NULL)
356    {
357      /*
358        16bit windows metafile.
359      */
360      dwSize=GetMetaFileBitsEx(hOld,0,NULL);
361      if (dwSize == 0)
362        {
363          DeleteMetaFile(hOld);
364          return((HENHMETAFILE) NULL);
365        }
366      pBits=(LPBYTE) AcquireQuantumMemory(dwSize,sizeof(*pBits));
367      if (pBits == (LPBYTE) NULL)
368        {
369          DeleteMetaFile(hOld);
370          return((HENHMETAFILE) NULL);
371        }
372      if (GetMetaFileBitsEx(hOld,dwSize,pBits) == 0)
373        {
374          pBits=(BYTE *) DestroyString((char *) pBits);
375          DeleteMetaFile(hOld);
376          return((HENHMETAFILE) NULL);
377        }
378      /*
379        Make an enhanced metafile from the windows metafile.
380      */
381      mp.mm=MM_ANISOTROPIC;
382      mp.xExt=1000;
383      mp.yExt=1000;
384      mp.hMF=NULL;
385      hDC=GetDC(NULL);
386      hTemp=SetWinMetaFileBits(dwSize,pBits,hDC,&mp);
387      ReleaseDC(NULL,hDC);
388      DeleteMetaFile(hOld);
389      pBits=(BYTE *) DestroyString((char *) pBits);
390      GetEnhMetaFileHeader(hTemp,sizeof(ENHMETAHEADER),&emfh);
391      *width=emfh.rclFrame.right-emfh.rclFrame.left;
392      *height=emfh.rclFrame.bottom-emfh.rclFrame.top;
393      return(hTemp);
394    }
395  /*
396    Aldus Placeable metafile.
397  */
398  hFile=CreateFile(path,GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,
399    NULL);
400  if (hFile == INVALID_HANDLE_VALUE)
401    return(NULL);
402  dwSize=GetFileSize(hFile,NULL);
403  pBits=(LPBYTE) AcquireQuantumMemory(dwSize,sizeof(*pBits));
404  ReadFile(hFile,pBits,dwSize,&dwSize,NULL);
405  CloseHandle(hFile);
406  if (((PAPMHEADER) pBits)->dwKey != 0x9ac6cdd7l)
407    {
408      pBits=(BYTE *) DestroyString((char *) pBits);
409      return((HENHMETAFILE) NULL);
410    }
411  /*
412    Make an enhanced metafile from the placable metafile.
413  */
414  mp.mm=MM_ANISOTROPIC;
415  mp.xExt=((PAPMHEADER) pBits)->bbox.Right-((PAPMHEADER) pBits)->bbox.Left;
416  *width=mp.xExt;
417  mp.xExt=(mp.xExt*2540l)/(DWORD) (((PAPMHEADER) pBits)->wInch);
418  mp.yExt=((PAPMHEADER)pBits)->bbox.Bottom-((PAPMHEADER) pBits)->bbox.Top;
419  *height=mp.yExt;
420  mp.yExt=(mp.yExt*2540l)/(DWORD) (((PAPMHEADER) pBits)->wInch);
421  mp.hMF=NULL;
422  hDC=GetDC(NULL);
423  hTemp=SetWinMetaFileBits(dwSize,&(pBits[sizeof(APMHEADER)]),hDC,&mp);
424  ReleaseDC(NULL,hDC);
425  pBits=(BYTE *) DestroyString((char *) pBits);
426  return(hTemp);
427}
428
429#define CENTIMETERS_INCH 2.54
430
431static Image *ReadEMFImage(const ImageInfo *image_info,
432  ExceptionInfo *exception)
433{
434  BITMAPINFO
435    DIBinfo;
436
437  HBITMAP
438    hBitmap,
439    hOldBitmap;
440
441  HDC
442    hDC;
443
444  HENHMETAFILE
445    hemf;
446
447  Image
448    *image;
449
450  long
451    height,
452    width,
453    y;
454
455  RECT
456    rect;
457
458  register long
459    x;
460
461  register PixelPacket
462    *q;
463
464  RGBQUAD
465    *pBits,
466    *ppBits;
467
468  image=AcquireImage(image_info);
469  hemf=ReadEnhMetaFile(image_info->filename,&width,&height);
470  if (hemf == (HENHMETAFILE) NULL)
471    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
472  if ((image->columns == 0) || (image->rows == 0))
473    {
474      double
475        y_resolution,
476        x_resolution;
477
478      y_resolution=DefaultResolution;
479      x_resolution=DefaultResolution;
480      if (image->y_resolution > 0)
481        {
482          y_resolution=image->y_resolution;
483          if (image->units == PixelsPerCentimeterResolution)
484            y_resolution*=CENTIMETERS_INCH;
485        }
486      if (image->x_resolution > 0)
487        {
488          x_resolution=image->x_resolution;
489          if (image->units == PixelsPerCentimeterResolution)
490            x_resolution*=CENTIMETERS_INCH;
491        }
492      image->rows=(unsigned long) ((height/1000.0/CENTIMETERS_INCH)*
493        y_resolution+0.5);
494      image->columns=(unsigned long) ((width/1000.0/CENTIMETERS_INCH)*
495        x_resolution+0.5);
496    }
497  if (image_info->size != (char *) NULL)
498    {
499      long
500        x;
501
502      image->columns=width;
503      image->rows=height;
504      x=0;
505      y=0;
506      (void) GetGeometry(image_info->size,&x,&y,&image->columns,&image->rows);
507    }
508  if (image_info->page != (char *) NULL)
509    {
510      char
511        *geometry;
512
513      long
514        sans;
515
516      register char
517        *p;
518
519      MagickStatusType
520        flags;
521
522      geometry=GetPageGeometry(image_info->page);
523      p=strchr(geometry,'>');
524      if (p == (char *) NULL)
525        {
526          flags=ParseMetaGeometry(geometry,&sans,&sans,&image->columns,
527            &image->rows);
528          if (image->x_resolution != 0.0)
529            image->columns=(unsigned long) ((image->columns*
530              image->x_resolution)+0.5);
531          if (image->y_resolution != 0.0)
532            image->rows=(unsigned long) ((image->rows*image->y_resolution)+0.5);
533        }
534      else
535        {
536          *p='\0';
537          flags=ParseMetaGeometry(geometry,&sans,&sans,&image->columns,
538            &image->rows);
539          if (image->x_resolution != 0.0)
540            image->columns=(unsigned long) (((image->columns*
541              image->x_resolution)/DefaultResolution)+0.5);
542          if (image->y_resolution != 0.0)
543            image->rows=(unsigned long) (((image->rows*image->y_resolution)/
544              DefaultResolution)+0.5);
545        }
546      geometry=DestroyString(geometry);
547    }
548  hDC=GetDC(NULL);
549  if (hDC == (HDC) NULL)
550    {
551      DeleteEnhMetaFile(hemf);
552      ThrowReaderException(ResourceLimitError,"UnableToCreateADC");
553    }
554  /*
555    Initialize the bitmap header info.
556  */
557  (void) ResetMagickMemory(&DIBinfo,0,sizeof(BITMAPINFO));
558  DIBinfo.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
559  DIBinfo.bmiHeader.biWidth=image->columns;
560  DIBinfo.bmiHeader.biHeight=(-1)*image->rows;
561  DIBinfo.bmiHeader.biPlanes=1;
562  DIBinfo.bmiHeader.biBitCount=32;
563  DIBinfo.bmiHeader.biCompression=BI_RGB;
564  hBitmap=CreateDIBSection(hDC,&DIBinfo,DIB_RGB_COLORS,(void **) &ppBits,
565    NULL,0);
566  ReleaseDC(NULL,hDC);
567  if (hBitmap == (HBITMAP) NULL)
568    {
569      DeleteEnhMetaFile(hemf);
570      ThrowReaderException(ResourceLimitError,"UnableToCreateBitmap");
571    }
572  hDC=CreateCompatibleDC(NULL);
573  if (hDC == (HDC) NULL)
574    {
575      DeleteEnhMetaFile(hemf);
576      DeleteObject(hBitmap);
577      ThrowReaderException(ResourceLimitError,"UnableToCreateADC");
578    }
579  hOldBitmap=(HBITMAP) SelectObject(hDC,hBitmap);
580  if (hOldBitmap == (HBITMAP) NULL)
581    {
582      DeleteEnhMetaFile(hemf);
583      DeleteDC(hDC);
584      DeleteObject(hBitmap);
585      ThrowReaderException(ResourceLimitError,"UnableToCreateBitmap");
586    }
587  /*
588    Initialize the bitmap to the image background color.
589  */
590  pBits=ppBits;
591  for (y=0; y < (long) image->rows; y++)
592  {
593    for (x=0; x < (long) image->columns; x++)
594    {
595      pBits->rgbRed=ScaleQuantumToChar(image->background_color.red);
596      pBits->rgbGreen=ScaleQuantumToChar(image->background_color.green);
597      pBits->rgbBlue=ScaleQuantumToChar(image->background_color.blue);
598      pBits++;
599    }
600  }
601  rect.top=0;
602  rect.left=0;
603  rect.right=image->columns;
604  rect.bottom=image->rows;
605  /*
606    Convert metafile pixels.
607  */
608  PlayEnhMetaFile(hDC,hemf,&rect);
609  pBits=ppBits;
610  for (y=0; y < (long) image->rows; y++)
611  {
612    q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
613    if (q == (PixelPacket *) NULL)
614      break;
615    for (x=0; x < (long) image->columns; x++)
616    {
617      q->red=ScaleCharToQuantum(pBits->rgbRed);
618      q->green=ScaleCharToQuantum(pBits->rgbGreen);
619      q->blue=ScaleCharToQuantum(pBits->rgbBlue);
620      q->opacity=OpaqueOpacity;
621      pBits++;
622      q++;
623    }
624    if (SyncAuthenticPixels(image,exception) == MagickFalse)
625      break;
626  }
627  DeleteEnhMetaFile(hemf);
628  SelectObject(hDC,hOldBitmap);
629  DeleteDC(hDC);
630  DeleteObject(hBitmap);
631  return(GetFirstImageInList(image));
632}
633#endif /* MAGICKCORE_WINGDI32_DELEGATE */
634
635/*
636%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
637%                                                                             %
638%                                                                             %
639%                                                                             %
640%   R e g i s t e r E M F I m a g e                                           %
641%                                                                             %
642%                                                                             %
643%                                                                             %
644%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
645%
646%  RegisterEMFImage() adds attributes for the EMF image format to
647%  the list of supported formats.  The attributes include the image format
648%  tag, a method to read and/or write the format, whether the format
649%  supports the saving of more than one frame to the same file or blob,
650%  whether the format supports native in-memory I/O, and a brief
651%  description of the format.
652%
653%  The format of the RegisterEMFImage method is:
654%
655%      unsigned long RegisterEMFImage(void)
656%
657*/
658ModuleExport unsigned long RegisterEMFImage(void)
659{
660  MagickInfo
661    *entry;
662
663  entry=SetMagickInfo("EMF");
664#if defined(MAGICKCORE_WINGDI32_DELEGATE)
665  entry->decoder=ReadEMFImage;
666#endif
667  entry->description=ConstantString(
668    "Windows WIN32 API rendered Enhanced Meta File");
669  entry->magick=(IsImageFormatHandler *) IsEMF;
670  entry->blob_support=MagickFalse;
671  entry->module=ConstantString("WMF");
672  (void) RegisterMagickInfo(entry);
673  entry=SetMagickInfo("WMFWIN32");
674#if defined(MAGICKCORE_WINGDI32_DELEGATE)
675  entry->decoder=ReadEMFImage;
676#endif
677  entry->description=ConstantString("Windows WIN32 API rendered Meta File");
678  entry->magick=(IsImageFormatHandler *) IsWMF;
679  entry->blob_support=MagickFalse;
680  entry->module=ConstantString("WMFWIN32");
681  (void) RegisterMagickInfo(entry);
682  return(MagickImageCoderSignature);
683}
684
685/*
686%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
687%                                                                             %
688%                                                                             %
689%                                                                             %
690%   U n r e g i s t e r E M F I m a g e                                       %
691%                                                                             %
692%                                                                             %
693%                                                                             %
694%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
695%
696%  UnregisterEMFImage() removes format registrations made by the
697%  EMF module from the list of supported formats.
698%
699%  The format of the UnregisterEMFImage method is:
700%
701%      UnregisterEMFImage(void)
702%
703*/
704ModuleExport void UnregisterEMFImage(void)
705{
706  (void) UnregisterMagickInfo("EMF");
707  (void) UnregisterMagickInfo("WMFWIN32");
708}
Note: See TracBrowser for help on using the browser.