]> granicus.if.org Git - imagemagick/blob - coders/emf.c
(no commit message)
[imagemagick] / coders / emf.c
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-2010 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 \f
36 /*
37  * Include declarations.
38  */
39
40 #include "magick/studio.h"
41 #if defined(MAGICKCORE_WINGDI32_DELEGATE)
42 #  if defined(__CYGWIN__)
43 #    include <windows.h>
44 #  else
45      /* All MinGW needs ... */
46 #    include <wingdi.h>
47 #  endif
48 #endif
49 \f
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 \f
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 */
91 static 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 \f
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 */
125 static 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 \f
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)
166 static 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
249 static 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 ssize_t
261         i;
262
263       /*
264         Not UTF-8, just copy.
265       */
266       length=strlen((char *) 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 <= (ssize_t) 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)
288 static HENHMETAFILE ReadEnhMetaFile(const char *path,ssize_t *width,
289   ssize_t *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((const unsigned char *) 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
431 static 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   ssize_t
451     height,
452     width,
453     y;
454
455   RECT
456     rect;
457
458   register ssize_t
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=(size_t) ((height/1000.0/CENTIMETERS_INCH)*
493         y_resolution+0.5);
494       image->columns=(size_t) ((width/1000.0/CENTIMETERS_INCH)*
495         x_resolution+0.5);
496     }
497   if (image_info->size != (char *) NULL)
498     {
499       ssize_t
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       ssize_t
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=(size_t) floor((image->columns*
530               image->x_resolution)+0.5);
531           if (image->y_resolution != 0.0)
532             image->rows=(size_t) floor((image->rows*image->y_resolution)+
533               0.5);
534         }
535       else
536         {
537           *p='\0';
538           flags=ParseMetaGeometry(geometry,&sans,&sans,&image->columns,
539             &image->rows);
540           if (image->x_resolution != 0.0)
541             image->columns=(size_t) floor(((image->columns*
542               image->x_resolution)/DefaultResolution)+0.5);
543           if (image->y_resolution != 0.0)
544             image->rows=(size_t) floor(((image->rows*
545               image->y_resolution)/DefaultResolution)+0.5);
546         }
547       geometry=DestroyString(geometry);
548     }
549   hDC=GetDC(NULL);
550   if (hDC == (HDC) NULL)
551     {
552       DeleteEnhMetaFile(hemf);
553       ThrowReaderException(ResourceLimitError,"UnableToCreateADC");
554     }
555   /*
556     Initialize the bitmap header info.
557   */
558   (void) ResetMagickMemory(&DIBinfo,0,sizeof(BITMAPINFO));
559   DIBinfo.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
560   DIBinfo.bmiHeader.biWidth=(LONG) image->columns;
561   DIBinfo.bmiHeader.biHeight=(-1)*(LONG) image->rows;
562   DIBinfo.bmiHeader.biPlanes=1;
563   DIBinfo.bmiHeader.biBitCount=32;
564   DIBinfo.bmiHeader.biCompression=BI_RGB;
565   hBitmap=CreateDIBSection(hDC,&DIBinfo,DIB_RGB_COLORS,(void **) &ppBits,
566     NULL,0);
567   ReleaseDC(NULL,hDC);
568   if (hBitmap == (HBITMAP) NULL)
569     {
570       DeleteEnhMetaFile(hemf);
571       ThrowReaderException(ResourceLimitError,"UnableToCreateBitmap");
572     }
573   hDC=CreateCompatibleDC(NULL);
574   if (hDC == (HDC) NULL)
575     {
576       DeleteEnhMetaFile(hemf);
577       DeleteObject(hBitmap);
578       ThrowReaderException(ResourceLimitError,"UnableToCreateADC");
579     }
580   hOldBitmap=(HBITMAP) SelectObject(hDC,hBitmap);
581   if (hOldBitmap == (HBITMAP) NULL)
582     {
583       DeleteEnhMetaFile(hemf);
584       DeleteDC(hDC);
585       DeleteObject(hBitmap);
586       ThrowReaderException(ResourceLimitError,"UnableToCreateBitmap");
587     }
588   /*
589     Initialize the bitmap to the image background color.
590   */
591   pBits=ppBits;
592   for (y=0; y < (ssize_t) image->rows; y++)
593   {
594     for (x=0; x < (ssize_t) image->columns; x++)
595     {
596       pBits->rgbRed=ScaleQuantumToChar(image->background_color.red);
597       pBits->rgbGreen=ScaleQuantumToChar(image->background_color.green);
598       pBits->rgbBlue=ScaleQuantumToChar(image->background_color.blue);
599       pBits++;
600     }
601   }
602   rect.top=0;
603   rect.left=0;
604   rect.right=(LONG) image->columns;
605   rect.bottom=(LONG) image->rows;
606   /*
607     Convert metafile pixels.
608   */
609   PlayEnhMetaFile(hDC,hemf,&rect);
610   pBits=ppBits;
611   for (y=0; y < (ssize_t) image->rows; y++)
612   {
613     q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
614     if (q == (PixelPacket *) NULL)
615       break;
616     for (x=0; x < (ssize_t) image->columns; x++)
617     {
618       q->red=ScaleCharToQuantum(pBits->rgbRed);
619       q->green=ScaleCharToQuantum(pBits->rgbGreen);
620       q->blue=ScaleCharToQuantum(pBits->rgbBlue);
621       SetOpacityPixelComponent(q,OpaqueOpacity);
622       pBits++;
623       q++;
624     }
625     if (SyncAuthenticPixels(image,exception) == MagickFalse)
626       break;
627   }
628   DeleteEnhMetaFile(hemf);
629   SelectObject(hDC,hOldBitmap);
630   DeleteDC(hDC);
631   DeleteObject(hBitmap);
632   return(GetFirstImageInList(image));
633 }
634 #endif /* MAGICKCORE_WINGDI32_DELEGATE */
635 \f
636 /*
637 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
638 %                                                                             %
639 %                                                                             %
640 %                                                                             %
641 %   R e g i s t e r E M F I m a g e                                           %
642 %                                                                             %
643 %                                                                             %
644 %                                                                             %
645 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
646 %
647 %  RegisterEMFImage() adds attributes for the EMF image format to
648 %  the list of supported formats.  The attributes include the image format
649 %  tag, a method to read and/or write the format, whether the format
650 %  supports the saving of more than one frame to the same file or blob,
651 %  whether the format supports native in-memory I/O, and a brief
652 %  description of the format.
653 %
654 %  The format of the RegisterEMFImage method is:
655 %
656 %      size_t RegisterEMFImage(void)
657 %
658 */
659 ModuleExport size_t RegisterEMFImage(void)
660 {
661   MagickInfo
662     *entry;
663
664   entry=SetMagickInfo("EMF");
665 #if defined(MAGICKCORE_WINGDI32_DELEGATE)
666   entry->decoder=ReadEMFImage;
667 #endif
668   entry->description=ConstantString(
669     "Windows WIN32 API rendered Enhanced Meta File");
670   entry->magick=(IsImageFormatHandler *) IsEMF;
671   entry->blob_support=MagickFalse;
672   entry->module=ConstantString("WMF");
673   (void) RegisterMagickInfo(entry);
674   entry=SetMagickInfo("WMFWIN32");
675 #if defined(MAGICKCORE_WINGDI32_DELEGATE)
676   entry->decoder=ReadEMFImage;
677 #endif
678   entry->description=ConstantString("Windows WIN32 API rendered Meta File");
679   entry->magick=(IsImageFormatHandler *) IsWMF;
680   entry->blob_support=MagickFalse;
681   entry->module=ConstantString("WMFWIN32");
682   (void) RegisterMagickInfo(entry);
683   return(MagickImageCoderSignature);
684 }
685 \f
686 /*
687 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
688 %                                                                             %
689 %                                                                             %
690 %                                                                             %
691 %   U n r e g i s t e r E M F I m a g e                                       %
692 %                                                                             %
693 %                                                                             %
694 %                                                                             %
695 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
696 %
697 %  UnregisterEMFImage() removes format registrations made by the
698 %  EMF module from the list of supported formats.
699 %
700 %  The format of the UnregisterEMFImage method is:
701 %
702 %      UnregisterEMFImage(void)
703 %
704 */
705 ModuleExport void UnregisterEMFImage(void)
706 {
707   (void) UnregisterMagickInfo("EMF");
708   (void) UnregisterMagickInfo("WMFWIN32");
709 }