From: dirk Date: Sun, 5 Jan 2014 14:05:25 +0000 (+0000) Subject: Moved code from emfplus.exe to coders\emf.c. X-Git-Tag: 7.0.1-0~2970 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=073ff37d5b7dc320b9cefaba23fe57a8d9719624;p=imagemagick Moved code from emfplus.exe to coders\emf.c. Removed wmf library from the windows distribution. --- diff --git a/MagickCore/coder.c b/MagickCore/coder.c index e6557c829..7960cd3f7 100644 --- a/MagickCore/coder.c +++ b/MagickCore/coder.c @@ -213,8 +213,10 @@ static const CoderMapInfo { "VDA", "TGA" }, { "VST", "TGA" }, { "WIZARD", "MAGICK" }, +#if defined(MAGICKCORE_WINGDI32_DELEGATE) + { "WMF", "EMF" }, +#endif { "WMV", "MPEG" }, - { "WMFWIN32", "EMF" }, { "WMZ", "WMF" }, { "X3f", "DNG" }, { "XMP", "META" }, diff --git a/coders/emf.c b/coders/emf.c index 0c753c654..b397bfeb7 100644 --- a/coders/emf.c +++ b/coders/emf.c @@ -15,6 +15,8 @@ % Software Design % % Bill Radcliffe % % 2001 % +% Dirk Lemstra % +% January 2014 % % % % Copyright 1999-2014 ImageMagick Studio LLC, a non-profit organization % % dedicated to making software imaging solutions freely available. % @@ -38,16 +40,9 @@ */ #include "MagickCore/studio.h" -#if defined(MAGICKCORE_WINGDI32_DELEGATE) && defined(__CYGWIN__) -# define MAGICKCORE_EMF_DELEGATE -#endif -#if defined(MAGICKCORE_EMF_DELEGATE) -# if defined(__CYGWIN__) -# include -# else -# include "MagickCore/nt-base-private.h" -# include -# endif +#if defined(MAGICKCORE_WINGDI32_DELEGATE) +# include +# pragma comment(lib, "gdiplus.lib") #endif #include "MagickCore/blob.h" #include "MagickCore/blob-private.h" @@ -166,474 +161,146 @@ static MagickBooleanType IsWMF(const unsigned char *magick,const size_t length) % */ - -#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_EMF_DELEGATE) -static HENHMETAFILE ReadEnhMetaFile(const char *path,ssize_t *width, - ssize_t *height) +#if defined(MAGICKCORE_WINGDI32_DELEGATE) +static Image *ReadEMFImage(const ImageInfo *image_info, + ExceptionInfo *exception) { -#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; + Gdiplus::Bitmap + *bitmap; - 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); -} + Gdiplus::BitmapData + bitmap_data; -#define CENTIMETERS_INCH 2.54 + Gdiplus::GdiplusStartupInput + startup_input; -static Image *ReadEMFImage(const ImageInfo *image_info, - ExceptionInfo *exception) -{ - BITMAPINFO - DIBinfo; + Gdiplus::Graphics + *graphics; - HBITMAP - hBitmap, - hOldBitmap; + Gdiplus::Image + *source; - HDC - hDC; + Gdiplus::Rect + rect; - HENHMETAFILE - hemf; + GeometryInfo + geometry_info; Image *image; - RECT - rect; - - register ssize_t - x; + MagickStatusType + flags; register Quantum *q; - RGBQUAD - *pBits, - *ppBits; + register ssize_t + x; ssize_t - height, - width, y; - image=AcquireImage(image_info,exception); - 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->resolution.y > 0) - { - y_resolution=image->resolution.y; - if (image->units == PixelsPerCentimeterResolution) - y_resolution*=CENTIMETERS_INCH; - } - if (image->resolution.x > 0) - { - x_resolution=image->resolution.x; - 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; + ULONG_PTR + token; - register char - *p; + unsigned char + *p; - MagickStatusType - flags; + wchar_t + fileName[MaxTextExtent]; - ssize_t - sans; + assert(image_info != (const ImageInfo *) NULL); + assert(image_info->signature == MagickSignature); + if (image_info->debug != MagickFalse) + (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s", + image_info->filename); + assert(exception != (ExceptionInfo *) NULL); - geometry=GetPageGeometry(image_info->page); - p=strchr(geometry,'>'); - if (p == (char *) NULL) - { - flags=ParseMetaGeometry(geometry,&sans,&sans,&image->columns, - &image->rows); - if (image->resolution.x != 0.0) - image->columns=(size_t) floor((image->columns*image->resolution.x)+ - 0.5); - if (image->resolution.y != 0.0) - image->rows=(size_t) floor((image->rows*image->resolution.y)+0.5); - } - else - { - *p='\0'; - flags=ParseMetaGeometry(geometry,&sans,&sans,&image->columns, - &image->rows); - if (image->resolution.x != 0.0) - image->columns=(size_t) floor(((image->columns*image->resolution.x)/ - DefaultResolution)+0.5); - if (image->resolution.y != 0.0) - image->rows=(size_t) floor(((image->rows*image->resolution.y)/ - DefaultResolution)+0.5); - } - (void) flags; - 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) + image=AcquireImage(image_info,exception); + if (Gdiplus::GdiplusStartup(&token,&startup_input,NULL) != + Gdiplus::Status::Ok) + ThrowReaderException(CoderError, "GdiplusStartupFailed"); + MultiByteToWideChar(CP_UTF8,0,image->filename,-1,fileName,MaxTextExtent); + source=Gdiplus::Image::FromFile(fileName); + if (source == nullptr) { - DeleteEnhMetaFile(hemf); - DeleteObject(hBitmap); - ThrowReaderException(ResourceLimitError,"UnableToCreateADC"); + Gdiplus::GdiplusShutdown(token); + ThrowReaderException(FileOpenError,"UnableToOpenFile"); } - hOldBitmap=(HBITMAP) SelectObject(hDC,hBitmap); - if (hOldBitmap == (HBITMAP) NULL) + + image->resolution.x=source->GetHorizontalResolution(); + image->resolution.y=source->GetVerticalResolution(); + image->columns=(size_t) source->GetWidth(); + image->rows=(size_t) source->GetHeight(); + if (image_info->density != (char *) NULL) { - DeleteEnhMetaFile(hemf); - DeleteDC(hDC); - DeleteObject(hBitmap); - ThrowReaderException(ResourceLimitError,"UnableToCreateBitmap"); + flags=ParseGeometry(image_info->density,&geometry_info); + image->resolution.x=geometry_info.rho; + image->resolution.y=geometry_info.sigma; + if ((flags & SigmaValue) == 0) + image->resolution.y=image->resolution.x; + if ((image->resolution.x > 0.0) && (image->resolution.y > 0.0)) + { + image->columns=(size_t) floor((Gdiplus::REAL) source->GetWidth() / + source->GetHorizontalResolution() * image->resolution.x + 0.5); + image->rows=(size_t)floor((Gdiplus::REAL) source->GetHeight() / + source->GetVerticalResolution() * image->resolution.y + 0.5); + } } - /* - Initialize the bitmap to the image background color. - */ - pBits=ppBits; - for (y=0; y < (ssize_t) image->rows; y++) + + bitmap=new Gdiplus::Bitmap((INT) image->columns,(INT) image->rows, + PixelFormat32bppARGB); + graphics=Gdiplus::Graphics::FromImage(bitmap); + graphics->SetInterpolationMode(Gdiplus::InterpolationModeHighQualityBicubic); + graphics->SetSmoothingMode(Gdiplus::SmoothingModeHighQuality); + graphics->SetTextRenderingHint(Gdiplus::TextRenderingHintClearTypeGridFit); + graphics->Clear(Gdiplus::Color((BYTE) ScaleQuantumToChar( + image->background_color.alpha),(BYTE) ScaleQuantumToChar( + image->background_color.red),(BYTE) ScaleQuantumToChar( + image->background_color.green),(BYTE) ScaleQuantumToChar( + image->background_color.blue))); + graphics->DrawImage(source,0,0,(INT) image->columns,(INT) image->rows); + delete graphics; + delete source; + + rect=Gdiplus::Rect(0,0,(INT) image->columns,(INT) image->rows); + if (bitmap->LockBits(&rect,Gdiplus::ImageLockModeRead,PixelFormat32bppARGB, + &bitmap_data) != Gdiplus::Ok) { - 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++; - } + delete bitmap; + Gdiplus::GdiplusShutdown(token); + ThrowReaderException(FileOpenError,"UnableToReadImageData"); } - 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; + + image->alpha_trait=BlendPixelTrait; for (y=0; y < (ssize_t) image->rows; y++) { - q=QueueAuthenticPixels(image,0,y,image->columns,1,exception); + p=(unsigned char *) bitmap_data.Scan0+(y*abs(bitmap_data.Stride)); + if (bitmap_data.Stride < 0) + q=GetAuthenticPixels(image,0,image->rows-y-1,image->columns,1,exception); + else + q=GetAuthenticPixels(image,0,y,image->columns,1,exception); if (q == (Quantum *) NULL) break; + for (x=0; x < (ssize_t) image->columns; x++) { - SetPixelRed(image,ScaleCharToQuantum(pBits->rgbRed),q); - SetPixelGreen(image,ScaleCharToQuantum(pBits->rgbGreen),q); - SetPixelBlue(image,ScaleCharToQuantum(pBits->rgbBlue),q); - SetPixelAlpha(image,OpaqueAlpha,q); - pBits++; + SetPixelBlue(image,ScaleCharToQuantum(*p++),q); + SetPixelGreen(image,ScaleCharToQuantum(*p++),q); + SetPixelRed(image,ScaleCharToQuantum(*p++),q); + SetPixelAlpha(image,ScaleCharToQuantum(*p++),q); q+=GetPixelChannels(image); } + if (SyncAuthenticPixels(image,exception) == MagickFalse) break; } - DeleteEnhMetaFile(hemf); - SelectObject(hDC,hOldBitmap); - DeleteDC(hDC); - DeleteObject(hBitmap); - return(GetFirstImageInList(image)); + + bitmap->UnlockBits(&bitmap_data); + delete bitmap; + Gdiplus::GdiplusShutdown(token); + return(image); } #endif /* MAGICKCORE_EMF_DELEGATE */ @@ -666,23 +333,23 @@ ModuleExport size_t RegisterEMFImage(void) *entry; entry=SetMagickInfo("EMF"); -#if defined(MAGICKCORE_EMF_DELEGATE) +#if defined(MAGICKCORE_WINGDI32_DELEGATE) entry->decoder=ReadEMFImage; #endif entry->description=ConstantString( - "Windows WIN32 API rendered Enhanced Meta File"); + "Windows Enhanced Meta File"); entry->magick=(IsImageFormatHandler *) IsEMF; entry->blob_support=MagickFalse; entry->module=ConstantString("WMF"); (void) RegisterMagickInfo(entry); - entry=SetMagickInfo("WMFWIN32"); -#if defined(MAGICKCORE_EMF_DELEGATE) + entry=SetMagickInfo("WMF"); +#if defined(MAGICKCORE_WINGDI32_DELEGATE) entry->decoder=ReadEMFImage; #endif - entry->description=ConstantString("Windows WIN32 API rendered Meta File"); + entry->description=ConstantString("Windows Meta File"); entry->magick=(IsImageFormatHandler *) IsWMF; entry->blob_support=MagickFalse; - entry->module=ConstantString("WMFWIN32"); + entry->module=ConstantString("WMF"); (void) RegisterMagickInfo(entry); return(MagickImageCoderSignature); } @@ -709,5 +376,5 @@ ModuleExport size_t RegisterEMFImage(void) ModuleExport void UnregisterEMFImage(void) { (void) UnregisterMagickInfo("EMF"); - (void) UnregisterMagickInfo("WMFWIN32"); + (void) UnregisterMagickInfo("WMF"); }