]> granicus.if.org Git - imagemagick/commitdiff
Moved code from emfplus.exe to coders\emf.c.
authordirk <dirk@git.imagemagick.org>
Sun, 5 Jan 2014 14:05:25 +0000 (14:05 +0000)
committerdirk <dirk@git.imagemagick.org>
Sun, 5 Jan 2014 14:05:25 +0000 (14:05 +0000)
Removed wmf library from the windows distribution.

MagickCore/coder.c
coders/emf.c

index e6557c8293978cf1a7a4c36d94f2d6b0d077f681..7960cd3f79bc120641c4cf30dfaae50a94b8c8df 100644 (file)
@@ -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" },
index 0c753c654a7884e855692507c5e71a6886de30ac..b397bfeb78707851bc0e6d3d1bdbd90db894e8bf 100644 (file)
@@ -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.           %
  */
 
 #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 <windows.h>
-#  else
-#    include "MagickCore/nt-base-private.h"
-#    include <wingdi.h>
-#  endif
+#if defined(MAGICKCORE_WINGDI32_DELEGATE)
+#  include <gdiplus.h>
+#  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 */
 \f
@@ -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");
 }