| /* | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                            EEEEE  M   M  FFFFF                              % | 
 | %                            E      MM MM  F                                  % | 
 | %                            EEE    M M M  FFF                                % | 
 | %                            E      M   M  F                                  % | 
 | %                            EEEEE  M   M  F                                  % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                  Read Windows Enahanced Metafile Format                     % | 
 | %                                                                             % | 
 | %                              Software Design                                % | 
 | %                              Bill Radcliffe                                 % | 
 | %                                   2001                                      % | 
 | %                                                                             % | 
 | %  Copyright 1999-2010 ImageMagick Studio LLC, a non-profit organization      % | 
 | %  dedicated to making software imaging solutions freely available.           % | 
 | %                                                                             % | 
 | %  You may not use this file except in compliance with the License.  You may  % | 
 | %  obtain a copy of the License at                                            % | 
 | %                                                                             % | 
 | %    http://www.imagemagick.org/script/license.php                            % | 
 | %                                                                             % | 
 | %  Unless required by applicable law or agreed to in writing, software        % | 
 | %  distributed under the License is distributed on an "AS IS" BASIS,          % | 
 | %  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   % | 
 | %  See the License for the specific language governing permissions and        % | 
 | %  limitations under the License.                                             % | 
 | %                                                                             % | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | */ | 
 |  | 
 | /* | 
 |  * Include declarations. | 
 |  */ | 
 |  | 
 | #include "magick/studio.h" | 
 | #if defined(MAGICKCORE_WINGDI32_DELEGATE) | 
 | #  if defined(__CYGWIN__) | 
 | #    include <windows.h> | 
 | #  else | 
 |      /* All MinGW needs ... */ | 
 | #    include <wingdi.h> | 
 | #  endif | 
 | #endif | 
 |  | 
 | #include "magick/blob.h" | 
 | #include "magick/blob-private.h" | 
 | #include "magick/cache.h" | 
 | #include "magick/exception.h" | 
 | #include "magick/exception-private.h" | 
 | #include "magick/geometry.h" | 
 | #include "magick/image.h" | 
 | #include "magick/image-private.h" | 
 | #include "magick/list.h" | 
 | #include "magick/magick.h" | 
 | #include "magick/memory_.h" | 
 | #include "magick/quantum-private.h" | 
 | #include "magick/static.h" | 
 | #include "magick/string_.h" | 
 | #include "magick/module.h" | 
 |  | 
 | /* | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %   I s E F M                                                                 % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | % | 
 | %  IsEMF() returns MagickTrue if the image format type, identified by the | 
 | %  magick string, is a Microsoft Windows Enhanced MetaFile (EMF) file. | 
 | % | 
 | %  The format of the ReadEMFImage method is: | 
 | % | 
 | %      MagickBooleanType IsEMF(const unsigned char *magick,const size_t length) | 
 | % | 
 | %  A description of each parameter follows: | 
 | % | 
 | %    o magick: compare image format pattern against these bytes. | 
 | % | 
 | %    o length: Specifies the length of the magick string. | 
 | % | 
 | */ | 
 | static MagickBooleanType IsEMF(const unsigned char *magick,const size_t length) | 
 | { | 
 |   if (length < 48) | 
 |     return(MagickFalse); | 
 |   if (memcmp(magick+40,"\040\105\115\106\000\000\001\000",8) == 0) | 
 |     return(MagickTrue); | 
 |   return(MagickFalse); | 
 | } | 
 |  | 
 | /* | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %   I s W M F                                                                 % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | % | 
 | %  IsWMF() returns MagickTrue if the image format type, identified by the | 
 | %  magick string, is a Windows MetaFile (WMF) file. | 
 | % | 
 | %  The format of the ReadEMFImage method is: | 
 | % | 
 | %      MagickBooleanType IsEMF(const unsigned char *magick,const size_t length) | 
 | % | 
 | %  A description of each parameter follows: | 
 | % | 
 | %    o magick: compare image format pattern against these bytes. | 
 | % | 
 | %    o length: Specifies the length of the magick string. | 
 | % | 
 | */ | 
 | static MagickBooleanType IsWMF(const unsigned char *magick,const size_t length) | 
 | { | 
 |   if (length < 4) | 
 |     return(MagickFalse); | 
 |   if (memcmp(magick,"\327\315\306\232",4) == 0) | 
 |     return(MagickTrue); | 
 |   if (memcmp(magick,"\001\000\011\000",4) == 0) | 
 |     return(MagickTrue); | 
 |   return(MagickFalse); | 
 | } | 
 |  | 
 | /* | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %  R e a d E M F I m a g e                                                    % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | % | 
 | %  ReadEMFImage() reads an Microsoft Windows Enhanced MetaFile (EMF) or | 
 | %  Windows MetaFile (WMF) file using the Windows API and returns it.  It | 
 | %  allocates the memory necessary for the new Image structure and returns a | 
 | %  pointer to the new image. | 
 | % | 
 | %  The format of the ReadEMFImage method is: | 
 | % | 
 | %      Image *ReadEMFImage(const ImageInfo *image_info, | 
 | %        ExceptionInfo *exception) | 
 | % | 
 | %  A description of each parameter follows: | 
 | % | 
 | %    o image_info: the image info.. | 
 | % | 
 | %    o exception: return any errors or warnings in this structure. | 
 | % | 
 | */ | 
 |  | 
 | #if defined(MAGICKCORE_HAVE__WFOPEN) | 
 | static size_t UTF8ToUTF16(const unsigned char *utf8,wchar_t *utf16) | 
 | { | 
 |   register const unsigned char | 
 |     *p; | 
 |  | 
 |   if (utf16 != (wchar_t *) NULL) | 
 |     { | 
 |       register wchar_t | 
 |         *q; | 
 |  | 
 |       wchar_t | 
 |         c; | 
 |  | 
 |       /* | 
 |         Convert UTF-8 to UTF-16. | 
 |       */ | 
 |       q=utf16; | 
 |       for (p=utf8; *p != '\0'; p++) | 
 |       { | 
 |         if ((*p & 0x80) == 0) | 
 |           *q=(*p); | 
 |         else | 
 |           if ((*p & 0xE0) == 0xC0) | 
 |             { | 
 |               c=(*p); | 
 |               *q=(c & 0x1F) << 6; | 
 |               p++; | 
 |               if ((*p & 0xC0) != 0x80) | 
 |                 return(0); | 
 |               *q|=(*p & 0x3F); | 
 |             } | 
 |           else | 
 |             if ((*p & 0xF0) == 0xE0) | 
 |               { | 
 |                 c=(*p); | 
 |                 *q=c << 12; | 
 |                 p++; | 
 |                 if ((*p & 0xC0) != 0x80) | 
 |                   return(0); | 
 |                 c=(*p); | 
 |                 *q|=(c & 0x3F) << 6; | 
 |                 p++; | 
 |                 if ((*p & 0xC0) != 0x80) | 
 |                   return(0); | 
 |                 *q|=(*p & 0x3F); | 
 |               } | 
 |             else | 
 |               return(0); | 
 |         q++; | 
 |       } | 
 |       *q++='\0'; | 
 |       return(q-utf16); | 
 |     } | 
 |   /* | 
 |     Compute UTF-16 string length. | 
 |   */ | 
 |   for (p=utf8; *p != '\0'; p++) | 
 |   { | 
 |     if ((*p & 0x80) == 0) | 
 |       ; | 
 |     else | 
 |       if ((*p & 0xE0) == 0xC0) | 
 |         { | 
 |           p++; | 
 |           if ((*p & 0xC0) != 0x80) | 
 |             return(0); | 
 |         } | 
 |       else | 
 |         if ((*p & 0xF0) == 0xE0) | 
 |           { | 
 |             p++; | 
 |             if ((*p & 0xC0) != 0x80) | 
 |               return(0); | 
 |             p++; | 
 |             if ((*p & 0xC0) != 0x80) | 
 |               return(0); | 
 |          } | 
 |        else | 
 |          return(0); | 
 |   } | 
 |   return(p-utf8); | 
 | } | 
 |  | 
 | static wchar_t *ConvertUTF8ToUTF16(const unsigned char *source) | 
 | { | 
 |   size_t | 
 |     length; | 
 |  | 
 |   wchar_t | 
 |     *utf16; | 
 |  | 
 |   length=UTF8ToUTF16(source,(wchar_t *) NULL); | 
 |   if (length == 0) | 
 |     { | 
 |       register ssize_t | 
 |         i; | 
 |  | 
 |       /* | 
 |         Not UTF-8, just copy. | 
 |       */ | 
 |       length=strlen((char *) source); | 
 |       utf16=(wchar_t *) AcquireQuantumMemory(length+1,sizeof(*utf16)); | 
 |       if (utf16 == (wchar_t *) NULL) | 
 |         return((wchar_t *) NULL); | 
 |       for (i=0; i <= (ssize_t) length; i++) | 
 |         utf16[i]=source[i]; | 
 |       return(utf16); | 
 |     } | 
 |   utf16=(wchar_t *) AcquireQuantumMemory(length+1,sizeof(*utf16)); | 
 |   if (utf16 == (wchar_t *) NULL) | 
 |     return((wchar_t *) NULL); | 
 |   length=UTF8ToUTF16(source,utf16); | 
 |   return(utf16); | 
 | } | 
 | #endif | 
 |  | 
 | /* | 
 |   This method reads either an enhanced metafile, a regular 16bit Windows | 
 |   metafile, or an Aldus Placeable metafile and converts it into an enhanced | 
 |   metafile.  Width and height are returned in .01mm units. | 
 | */ | 
 | #if defined(MAGICKCORE_WINGDI32_DELEGATE) | 
 | static HENHMETAFILE ReadEnhMetaFile(const char *path,ssize_t *width, | 
 |   ssize_t *height) | 
 | { | 
 | #pragma pack( push, 2 ) | 
 |   typedef struct | 
 |   { | 
 |     DWORD dwKey; | 
 |     WORD hmf; | 
 |     SMALL_RECT bbox; | 
 |     WORD wInch; | 
 |     DWORD dwReserved; | 
 |     WORD wCheckSum; | 
 |   } APMHEADER, *PAPMHEADER; | 
 | #pragma pack( pop ) | 
 |  | 
 |   DWORD | 
 |     dwSize; | 
 |  | 
 |   ENHMETAHEADER | 
 |     emfh; | 
 |  | 
 |   HANDLE | 
 |     hFile; | 
 |  | 
 |   HDC | 
 |     hDC; | 
 |  | 
 |   HENHMETAFILE | 
 |     hTemp; | 
 |  | 
 |   LPBYTE | 
 |     pBits; | 
 |  | 
 |   METAFILEPICT | 
 |     mp; | 
 |  | 
 |   HMETAFILE | 
 |     hOld; | 
 |  | 
 |   *width=512; | 
 |   *height=512; | 
 |   hTemp=GetEnhMetaFile(path); | 
 | #if defined(MAGICKCORE_HAVE__WFOPEN) | 
 |   if (hTemp == (HENHMETAFILE) NULL) | 
 |     { | 
 |       wchar_t | 
 |         *unicode_path; | 
 |  | 
 |       unicode_path=ConvertUTF8ToUTF16((const unsigned char *) path); | 
 |       if (unicode_path != (wchar_t *) NULL) | 
 |         { | 
 |           hTemp=GetEnhMetaFileW(unicode_path); | 
 |           unicode_path=(wchar_t *) RelinquishMagickMemory(unicode_path); | 
 |         } | 
 |     } | 
 | #endif | 
 |   if (hTemp != (HENHMETAFILE) NULL) | 
 |     { | 
 |       /* | 
 |         Enhanced metafile. | 
 |       */ | 
 |       GetEnhMetaFileHeader(hTemp,sizeof(ENHMETAHEADER),&emfh); | 
 |       *width=emfh.rclFrame.right-emfh.rclFrame.left; | 
 |       *height=emfh.rclFrame.bottom-emfh.rclFrame.top; | 
 |       return(hTemp); | 
 |     } | 
 |   hOld=GetMetaFile(path); | 
 |   if (hOld != (HMETAFILE) NULL) | 
 |     { | 
 |       /* | 
 |         16bit windows metafile. | 
 |       */ | 
 |       dwSize=GetMetaFileBitsEx(hOld,0,NULL); | 
 |       if (dwSize == 0) | 
 |         { | 
 |           DeleteMetaFile(hOld); | 
 |           return((HENHMETAFILE) NULL); | 
 |         } | 
 |       pBits=(LPBYTE) AcquireQuantumMemory(dwSize,sizeof(*pBits)); | 
 |       if (pBits == (LPBYTE) NULL) | 
 |         { | 
 |           DeleteMetaFile(hOld); | 
 |           return((HENHMETAFILE) NULL); | 
 |         } | 
 |       if (GetMetaFileBitsEx(hOld,dwSize,pBits) == 0) | 
 |         { | 
 |           pBits=(BYTE *) DestroyString((char *) pBits); | 
 |           DeleteMetaFile(hOld); | 
 |           return((HENHMETAFILE) NULL); | 
 |         } | 
 |       /* | 
 |         Make an enhanced metafile from the windows metafile. | 
 |       */ | 
 |       mp.mm=MM_ANISOTROPIC; | 
 |       mp.xExt=1000; | 
 |       mp.yExt=1000; | 
 |       mp.hMF=NULL; | 
 |       hDC=GetDC(NULL); | 
 |       hTemp=SetWinMetaFileBits(dwSize,pBits,hDC,&mp); | 
 |       ReleaseDC(NULL,hDC); | 
 |       DeleteMetaFile(hOld); | 
 |       pBits=(BYTE *) DestroyString((char *) pBits); | 
 |       GetEnhMetaFileHeader(hTemp,sizeof(ENHMETAHEADER),&emfh); | 
 |       *width=emfh.rclFrame.right-emfh.rclFrame.left; | 
 |       *height=emfh.rclFrame.bottom-emfh.rclFrame.top; | 
 |       return(hTemp); | 
 |     } | 
 |   /* | 
 |     Aldus Placeable metafile. | 
 |   */ | 
 |   hFile=CreateFile(path,GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL, | 
 |     NULL); | 
 |   if (hFile == INVALID_HANDLE_VALUE) | 
 |     return(NULL); | 
 |   dwSize=GetFileSize(hFile,NULL); | 
 |   pBits=(LPBYTE) AcquireQuantumMemory(dwSize,sizeof(*pBits)); | 
 |   ReadFile(hFile,pBits,dwSize,&dwSize,NULL); | 
 |   CloseHandle(hFile); | 
 |   if (((PAPMHEADER) pBits)->dwKey != 0x9ac6cdd7l) | 
 |     { | 
 |       pBits=(BYTE *) DestroyString((char *) pBits); | 
 |       return((HENHMETAFILE) NULL); | 
 |     } | 
 |   /* | 
 |     Make an enhanced metafile from the placable metafile. | 
 |   */ | 
 |   mp.mm=MM_ANISOTROPIC; | 
 |   mp.xExt=((PAPMHEADER) pBits)->bbox.Right-((PAPMHEADER) pBits)->bbox.Left; | 
 |   *width=mp.xExt; | 
 |   mp.xExt=(mp.xExt*2540l)/(DWORD) (((PAPMHEADER) pBits)->wInch); | 
 |   mp.yExt=((PAPMHEADER)pBits)->bbox.Bottom-((PAPMHEADER) pBits)->bbox.Top; | 
 |   *height=mp.yExt; | 
 |   mp.yExt=(mp.yExt*2540l)/(DWORD) (((PAPMHEADER) pBits)->wInch); | 
 |   mp.hMF=NULL; | 
 |   hDC=GetDC(NULL); | 
 |   hTemp=SetWinMetaFileBits(dwSize,&(pBits[sizeof(APMHEADER)]),hDC,&mp); | 
 |   ReleaseDC(NULL,hDC); | 
 |   pBits=(BYTE *) DestroyString((char *) pBits); | 
 |   return(hTemp); | 
 | } | 
 |  | 
 | #define CENTIMETERS_INCH 2.54 | 
 |  | 
 | static Image *ReadEMFImage(const ImageInfo *image_info, | 
 |   ExceptionInfo *exception) | 
 | { | 
 |   BITMAPINFO | 
 |     DIBinfo; | 
 |  | 
 |   HBITMAP | 
 |     hBitmap, | 
 |     hOldBitmap; | 
 |  | 
 |   HDC | 
 |     hDC; | 
 |  | 
 |   HENHMETAFILE | 
 |     hemf; | 
 |  | 
 |   Image | 
 |     *image; | 
 |  | 
 |   ssize_t | 
 |     height, | 
 |     width, | 
 |     y; | 
 |  | 
 |   RECT | 
 |     rect; | 
 |  | 
 |   register ssize_t | 
 |     x; | 
 |  | 
 |   register PixelPacket | 
 |     *q; | 
 |  | 
 |   RGBQUAD | 
 |     *pBits, | 
 |     *ppBits; | 
 |  | 
 |   image=AcquireImage(image_info); | 
 |   hemf=ReadEnhMetaFile(image_info->filename,&width,&height); | 
 |   if (hemf == (HENHMETAFILE) NULL) | 
 |     ThrowReaderException(CorruptImageError,"ImproperImageHeader"); | 
 |   if ((image->columns == 0) || (image->rows == 0)) | 
 |     { | 
 |       double | 
 |         y_resolution, | 
 |         x_resolution; | 
 |  | 
 |       y_resolution=DefaultResolution; | 
 |       x_resolution=DefaultResolution; | 
 |       if (image->y_resolution > 0) | 
 |         { | 
 |           y_resolution=image->y_resolution; | 
 |           if (image->units == PixelsPerCentimeterResolution) | 
 |             y_resolution*=CENTIMETERS_INCH; | 
 |         } | 
 |       if (image->x_resolution > 0) | 
 |         { | 
 |           x_resolution=image->x_resolution; | 
 |           if (image->units == PixelsPerCentimeterResolution) | 
 |             x_resolution*=CENTIMETERS_INCH; | 
 |         } | 
 |       image->rows=(size_t) ((height/1000.0/CENTIMETERS_INCH)* | 
 |         y_resolution+0.5); | 
 |       image->columns=(size_t) ((width/1000.0/CENTIMETERS_INCH)* | 
 |         x_resolution+0.5); | 
 |     } | 
 |   if (image_info->size != (char *) NULL) | 
 |     { | 
 |       ssize_t | 
 |         x; | 
 |  | 
 |       image->columns=width; | 
 |       image->rows=height; | 
 |       x=0; | 
 |       y=0; | 
 |       (void) GetGeometry(image_info->size,&x,&y,&image->columns,&image->rows); | 
 |     } | 
 |   if (image_info->page != (char *) NULL) | 
 |     { | 
 |       char | 
 |         *geometry; | 
 |  | 
 |       ssize_t | 
 |         sans; | 
 |  | 
 |       register char | 
 |         *p; | 
 |  | 
 |       MagickStatusType | 
 |         flags; | 
 |  | 
 |       geometry=GetPageGeometry(image_info->page); | 
 |       p=strchr(geometry,'>'); | 
 |       if (p == (char *) NULL) | 
 |         { | 
 |           flags=ParseMetaGeometry(geometry,&sans,&sans,&image->columns, | 
 |             &image->rows); | 
 |           if (image->x_resolution != 0.0) | 
 |             image->columns=(size_t) floor((image->columns* | 
 |               image->x_resolution)+0.5); | 
 |           if (image->y_resolution != 0.0) | 
 |             image->rows=(size_t) floor((image->rows*image->y_resolution)+ | 
 |               0.5); | 
 |         } | 
 |       else | 
 |         { | 
 |           *p='\0'; | 
 |           flags=ParseMetaGeometry(geometry,&sans,&sans,&image->columns, | 
 |             &image->rows); | 
 |           if (image->x_resolution != 0.0) | 
 |             image->columns=(size_t) floor(((image->columns* | 
 |               image->x_resolution)/DefaultResolution)+0.5); | 
 |           if (image->y_resolution != 0.0) | 
 |             image->rows=(size_t) floor(((image->rows* | 
 |               image->y_resolution)/DefaultResolution)+0.5); | 
 |         } | 
 |       geometry=DestroyString(geometry); | 
 |     } | 
 |   hDC=GetDC(NULL); | 
 |   if (hDC == (HDC) NULL) | 
 |     { | 
 |       DeleteEnhMetaFile(hemf); | 
 |       ThrowReaderException(ResourceLimitError,"UnableToCreateADC"); | 
 |     } | 
 |   /* | 
 |     Initialize the bitmap header info. | 
 |   */ | 
 |   (void) ResetMagickMemory(&DIBinfo,0,sizeof(BITMAPINFO)); | 
 |   DIBinfo.bmiHeader.biSize=sizeof(BITMAPINFOHEADER); | 
 |   DIBinfo.bmiHeader.biWidth=(LONG) image->columns; | 
 |   DIBinfo.bmiHeader.biHeight=(-1)*(LONG) image->rows; | 
 |   DIBinfo.bmiHeader.biPlanes=1; | 
 |   DIBinfo.bmiHeader.biBitCount=32; | 
 |   DIBinfo.bmiHeader.biCompression=BI_RGB; | 
 |   hBitmap=CreateDIBSection(hDC,&DIBinfo,DIB_RGB_COLORS,(void **) &ppBits, | 
 |     NULL,0); | 
 |   ReleaseDC(NULL,hDC); | 
 |   if (hBitmap == (HBITMAP) NULL) | 
 |     { | 
 |       DeleteEnhMetaFile(hemf); | 
 |       ThrowReaderException(ResourceLimitError,"UnableToCreateBitmap"); | 
 |     } | 
 |   hDC=CreateCompatibleDC(NULL); | 
 |   if (hDC == (HDC) NULL) | 
 |     { | 
 |       DeleteEnhMetaFile(hemf); | 
 |       DeleteObject(hBitmap); | 
 |       ThrowReaderException(ResourceLimitError,"UnableToCreateADC"); | 
 |     } | 
 |   hOldBitmap=(HBITMAP) SelectObject(hDC,hBitmap); | 
 |   if (hOldBitmap == (HBITMAP) NULL) | 
 |     { | 
 |       DeleteEnhMetaFile(hemf); | 
 |       DeleteDC(hDC); | 
 |       DeleteObject(hBitmap); | 
 |       ThrowReaderException(ResourceLimitError,"UnableToCreateBitmap"); | 
 |     } | 
 |   /* | 
 |     Initialize the bitmap to the image background color. | 
 |   */ | 
 |   pBits=ppBits; | 
 |   for (y=0; y < (ssize_t) image->rows; y++) | 
 |   { | 
 |     for (x=0; x < (ssize_t) image->columns; x++) | 
 |     { | 
 |       pBits->rgbRed=ScaleQuantumToChar(image->background_color.red); | 
 |       pBits->rgbGreen=ScaleQuantumToChar(image->background_color.green); | 
 |       pBits->rgbBlue=ScaleQuantumToChar(image->background_color.blue); | 
 |       pBits++; | 
 |     } | 
 |   } | 
 |   rect.top=0; | 
 |   rect.left=0; | 
 |   rect.right=(LONG) image->columns; | 
 |   rect.bottom=(LONG) image->rows; | 
 |   /* | 
 |     Convert metafile pixels. | 
 |   */ | 
 |   PlayEnhMetaFile(hDC,hemf,&rect); | 
 |   pBits=ppBits; | 
 |   for (y=0; y < (ssize_t) image->rows; y++) | 
 |   { | 
 |     q=QueueAuthenticPixels(image,0,y,image->columns,1,exception); | 
 |     if (q == (PixelPacket *) NULL) | 
 |       break; | 
 |     for (x=0; x < (ssize_t) image->columns; x++) | 
 |     { | 
 |       q->red=ScaleCharToQuantum(pBits->rgbRed); | 
 |       q->green=ScaleCharToQuantum(pBits->rgbGreen); | 
 |       q->blue=ScaleCharToQuantum(pBits->rgbBlue); | 
 |       SetOpacityPixelComponent(q,OpaqueOpacity); | 
 |       pBits++; | 
 |       q++; | 
 |     } | 
 |     if (SyncAuthenticPixels(image,exception) == MagickFalse) | 
 |       break; | 
 |   } | 
 |   DeleteEnhMetaFile(hemf); | 
 |   SelectObject(hDC,hOldBitmap); | 
 |   DeleteDC(hDC); | 
 |   DeleteObject(hBitmap); | 
 |   return(GetFirstImageInList(image)); | 
 | } | 
 | #endif /* MAGICKCORE_WINGDI32_DELEGATE */ | 
 |  | 
 | /* | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %   R e g i s t e r E M F I m a g e                                           % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | % | 
 | %  RegisterEMFImage() adds attributes for the EMF image format to | 
 | %  the list of supported formats.  The attributes include the image format | 
 | %  tag, a method to read and/or write the format, whether the format | 
 | %  supports the saving of more than one frame to the same file or blob, | 
 | %  whether the format supports native in-memory I/O, and a brief | 
 | %  description of the format. | 
 | % | 
 | %  The format of the RegisterEMFImage method is: | 
 | % | 
 | %      size_t RegisterEMFImage(void) | 
 | % | 
 | */ | 
 | ModuleExport size_t RegisterEMFImage(void) | 
 | { | 
 |   MagickInfo | 
 |     *entry; | 
 |  | 
 |   entry=SetMagickInfo("EMF"); | 
 | #if defined(MAGICKCORE_WINGDI32_DELEGATE) | 
 |   entry->decoder=ReadEMFImage; | 
 | #endif | 
 |   entry->description=ConstantString( | 
 |     "Windows WIN32 API rendered Enhanced Meta File"); | 
 |   entry->magick=(IsImageFormatHandler *) IsEMF; | 
 |   entry->blob_support=MagickFalse; | 
 |   entry->module=ConstantString("WMF"); | 
 |   (void) RegisterMagickInfo(entry); | 
 |   entry=SetMagickInfo("WMFWIN32"); | 
 | #if defined(MAGICKCORE_WINGDI32_DELEGATE) | 
 |   entry->decoder=ReadEMFImage; | 
 | #endif | 
 |   entry->description=ConstantString("Windows WIN32 API rendered Meta File"); | 
 |   entry->magick=(IsImageFormatHandler *) IsWMF; | 
 |   entry->blob_support=MagickFalse; | 
 |   entry->module=ConstantString("WMFWIN32"); | 
 |   (void) RegisterMagickInfo(entry); | 
 |   return(MagickImageCoderSignature); | 
 | } | 
 |  | 
 | /* | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %   U n r e g i s t e r E M F I m a g e                                       % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %                                                                             % | 
 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 
 | % | 
 | %  UnregisterEMFImage() removes format registrations made by the | 
 | %  EMF module from the list of supported formats. | 
 | % | 
 | %  The format of the UnregisterEMFImage method is: | 
 | % | 
 | %      UnregisterEMFImage(void) | 
 | % | 
 | */ | 
 | ModuleExport void UnregisterEMFImage(void) | 
 | { | 
 |   (void) UnregisterMagickInfo("EMF"); | 
 |   (void) UnregisterMagickInfo("WMFWIN32"); | 
 | } |