]> granicus.if.org Git - imagemagick/blobdiff - coders/wmf.c
(no commit message)
[imagemagick] / coders / wmf.c
index 75b2ae21baa6eaca1c65c210a60993946fde6afa..a17968568c777920c2a544db2c03a54a6e4907f8 100644 (file)
 %                        Read Windows Metafile Format                         %
 %                                                                             %
 %                              Software Design                                %
-%                              Bob Friesenhahn                                %
-%                            Dec 2000 - May 2001                              %
-%                            Oct 2001 - May 2002                              %
+%                                John Cristy                                  %
+%                               December 2000                                 %
 %                                                                             %
-%                           Port to libwmf 0.2 API                            %
-%                            Francis J. Franklin                              %
-%                            May 2001 - Oct 2001                              %
 %                                                                             %
-%                                                                             %
-%  Copyright 1999-2010 ImageMagick Studio LLC, a non-profit organization      %
+%  Copyright 1999-2013 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  %
 /*
   Include declarations.
 */
-#include "magick/studio.h"
-#include "magick/property.h"
-#include "magick/blob.h"
-#include "magick/blob-private.h"
-#include "magick/color.h"
-#include "magick/color-private.h"
-#include "magick/constitute.h"
-#include "magick/exception.h"
-#include "magick/exception-private.h"
-#include "magick/image.h"
-#include "magick/image-private.h"
-#include "magick/list.h"
-#include "magick/log.h"
-#include "magick/magick.h"
-#include "magick/memory_.h"
-#include "magick/monitor.h"
-#include "magick/monitor-private.h"
-#include "magick/paint.h"
-#include "magick/quantum-private.h"
-#include "magick/static.h"
-#include "magick/string_.h"
-#include "magick/module.h"
-#include "magick/type.h"
-#include "magick/module.h"
-#include "wand/MagickWand.h"
+#include "MagickCore/studio.h"
+#include "MagickCore/property.h"
+#include "MagickCore/blob.h"
+#include "MagickCore/blob-private.h"
+#include "MagickCore/color.h"
+#include "MagickCore/color-private.h"
+#include "MagickCore/constitute.h"
+#include "MagickCore/exception.h"
+#include "MagickCore/exception-private.h"
+#include "MagickCore/image.h"
+#include "MagickCore/image-private.h"
+#include "MagickCore/list.h"
+#include "MagickCore/log.h"
+#include "MagickCore/magick.h"
+#include "MagickCore/memory_.h"
+#include "MagickCore/monitor.h"
+#include "MagickCore/monitor-private.h"
+#include "MagickCore/paint.h"
+#include "MagickCore/quantum-private.h"
+#include "MagickCore/static.h"
+#include "MagickCore/string_.h"
+#include "MagickCore/module.h"
+#include "MagickCore/type.h"
+#include "MagickCore/module.h"
+#include "MagickWand/MagickWand.h"
+
+#if defined(__CYGWIN__)
+#undef MAGICKCORE_WMF_DELEGATE 
+#endif
 
-#if defined(MAGICKCORE_WMF_DELEGATE) || defined(MAGICKCORE_WMFLITE_DELEGATE)
+#if defined(MAGICKCORE_WMF_DELEGATE)
+#include "libwmf/api.h"
+#include "libwmf/eps.h"
+\f
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%                                                                             %
+%                                                                             %
+%                                                                             %
+%   R e a d W M F I m a g e                                                   %
+%                                                                             %
+%                                                                             %
+%                                                                             %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%  ReadWMFImage() reads an Windows Metafile image file 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 ReadWMFImage method is:
+%
+%      Image *ReadWMFImage(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.
+%
+*/
+
+static int WMFReadBlob(void *image)
+{
+  return(ReadBlobByte((Image *) image));
+}
+
+static int WMFSeekBlob(void *image,long offset)
+{
+  return((int) SeekBlob((Image *) image,(MagickOffsetType) offset,SEEK_SET));
+}
+
+static long WMFTellBlob(void *image)
+{
+  return((long) TellBlob((Image*) image));
+}
+
+static Image *ReadWMFImage(const ImageInfo *image_info,ExceptionInfo *exception)
+{
+  char
+    filename[MaxTextExtent];
+
+  int
+    unique_file;
+
+  FILE
+    *file;
+
+  Image
+    *image;
+
+  ImageInfo
+    *read_info;
+
+  MagickBooleanType
+    status;
+
+  size_t
+    flags;
+
+  wmfAPI
+    *wmf_info;
+
+  wmfAPI_Options
+    options;
+
+  wmfD_Rect
+    bounding_box;
+
+  wmf_eps_t
+    *eps_info;
+
+  wmf_error_t
+    wmf_status;
+
+  /*
+    Read WMF image.
+  */
+  image=AcquireImage(image_info,exception);
+  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
+  if (status == MagickFalse)
+    {
+      image=DestroyImageList(image);
+      return((Image *) NULL);
+    }
+  wmf_info=(wmfAPI *) NULL;
+  flags=0;
+  flags|=WMF_OPT_IGNORE_NONFATAL;
+  flags|=WMF_OPT_FUNCTION;
+  options.function=wmf_eps_function;
+  wmf_status=wmf_api_create(&wmf_info,(unsigned long) flags,&options);
+  if (wmf_status != wmf_E_None)
+    {
+      if (wmf_info != (wmfAPI *) NULL)
+        wmf_api_destroy(wmf_info);
+      ThrowReaderException(DelegateError,"UnableToInitializeWMFLibrary");
+    }
+  wmf_status=wmf_bbuf_input(wmf_info,WMFReadBlob,WMFSeekBlob,WMFTellBlob,
+    (void *) image);
+  if (wmf_status != wmf_E_None)
+    {
+      wmf_api_destroy(wmf_info);
+      ThrowFileException(exception,FileOpenError,"UnableToOpenFile",
+        image->filename);
+      image=DestroyImageList(image);
+      return((Image *) NULL);
+    }
+  wmf_status=wmf_scan(wmf_info,0,&bounding_box);
+  if (wmf_status != wmf_E_None)
+    {
+      wmf_api_destroy(wmf_info);
+      ThrowReaderException(DelegateError,"FailedToScanFile");
+    }
+  eps_info=WMF_EPS_GetData(wmf_info);
+  file=(FILE *) NULL;
+  unique_file=AcquireUniqueFileResource(filename);
+  if (unique_file != -1)
+    file=fdopen(unique_file,"wb");
+  if ((unique_file == -1) || (file == (FILE *) NULL))
+    {
+      wmf_api_destroy(wmf_info);
+      ThrowReaderException(FileOpenError,"UnableToCreateTemporaryFile");
+    }
+  eps_info->out=wmf_stream_create(wmf_info,file);
+  eps_info->bbox=bounding_box;
+  wmf_status=wmf_play(wmf_info,0,&bounding_box);
+  if (wmf_status != wmf_E_None)
+    {
+      wmf_api_destroy(wmf_info);
+      ThrowReaderException(DelegateError,"FailedToRenderFile");
+    }
+  (void) fclose(file);
+  wmf_api_destroy(wmf_info);
+  (void) CloseBlob(image);
+  image=DestroyImage(image);
+  /*
+    Read EPS image.
+  */
+  read_info=CloneImageInfo(image_info);
+  SetImageInfoBlob(read_info,(void *) NULL,0);
+  (void) FormatLocaleString(read_info->filename,MaxTextExtent,"eps:%s",
+    filename);
+  image=ReadImage(read_info,exception);
+  read_info=DestroyImageInfo(read_info);
+  if (image != (Image *) NULL)
+    {
+      (void) CopyMagickString(image->filename,image_info->filename,
+        MaxTextExtent);
+      (void) CopyMagickString(image->magick_filename,image_info->filename,
+        MaxTextExtent);
+      (void) CopyMagickString(image->magick,"WMF",MaxTextExtent);
+    }
+  (void) RelinquishUniqueFileResource(filename);
+  return(GetFirstImageInList(image));
+}
+#elif defined(MAGICKCORE_WMFLITE_DELEGATE)
 
 #define ERR(API)  ((API)->err != wmf_E_None)
 #define XC(x) ((double) x)
@@ -169,6 +332,9 @@ struct _wmf_magick_t
   DrawingWand
     *draw_wand;
 
+  ExceptionInfo
+    *exception;
+
   /* ImageMagick image */
   Image
     *image;
@@ -272,7 +438,7 @@ static void         util_draw_arc(wmfAPI * API, wmfDrawArc_t * draw_arc,magick_a
 #if defined(MAGICKCORE_WMFLITE_DELEGATE)
 /*static int          util_font_weight( const char* font );*/
 #endif
-static double       util_pointsize( wmfAPI* API, wmfFont* font, char* str, double font_height);
+static double       util_pointsize( wmfAPI* API, wmfFont* font, char* str, double font_height, ExceptionInfo *);
 static void         util_set_brush(wmfAPI * API, wmfDC * dc, const BrushApply brush_apply);
 static void         util_set_pen(wmfAPI * API, wmfDC * dc);
 
@@ -285,16 +451,8 @@ int magick_progress_callback(void *context,float quantum)
   MagickBooleanType
     status;
 
-  MagickOffsetType
-    offset;
-
-  MagickSizeType
-    span;
-
   image=(Image *) context;
   assert(image->signature == MagickSignature);
-  offset=(MagickOffsetType) floor((double) (100.0*quantum));
-  span=100;
   status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
     GetBlobSize(image));
   return(status == MagickTrue ? 0 : 1);
@@ -320,7 +478,7 @@ static void draw_fill_color_rgb( wmfAPI* API, const wmfRGB* rgb )
   PixelSetRedQuantum(fill_color,ScaleCharToQuantum(rgb->r));
   PixelSetGreenQuantum(fill_color,ScaleCharToQuantum(rgb->g));
   PixelSetBlueQuantum(fill_color,ScaleCharToQuantum(rgb->b));
-  PixelSetOpacityQuantum(fill_color,OpaqueOpacity);
+  PixelSetAlphaQuantum(fill_color,OpaqueAlpha);
   DrawSetFillColor(WmfDrawingWand,fill_color);
   fill_color=DestroyPixelWand(fill_color);
 }
@@ -346,7 +504,7 @@ static void draw_stroke_color_rgb( wmfAPI* API, const wmfRGB* rgb )
   PixelSetRedQuantum(stroke_color,ScaleCharToQuantum(rgb->r));
   PixelSetGreenQuantum(stroke_color,ScaleCharToQuantum(rgb->g));
   PixelSetBlueQuantum(stroke_color,ScaleCharToQuantum(rgb->b));
-  PixelSetOpacityQuantum(stroke_color,OpaqueOpacity);
+  PixelSetAlphaQuantum(stroke_color,OpaqueAlpha);
   DrawSetStrokeColor(WmfDrawingWand,stroke_color);
   stroke_color=DestroyPixelWand(stroke_color);
 }
@@ -371,7 +529,7 @@ static void draw_pattern_push( wmfAPI* API,
   char
     pattern_id[30];
 
-  (void) FormatMagickString(pattern_id,MaxTextExtent,"brush_%lu",id);
+  (void) FormatLocaleString(pattern_id,MaxTextExtent,"brush_%lu",id);
   (void) DrawPushPattern(WmfDrawingWand,pattern_id,0,0,columns,rows);
 }
 
@@ -482,7 +640,7 @@ static void ipa_bmp_draw(wmfAPI *API, wmfBMP_Draw_t *bmp_draw)
     *ddata = WMF_MAGICK_GetData(API);
 
   ExceptionInfo
-    exception;
+    *exception;
 
   Image
     *image;
@@ -490,24 +648,21 @@ static void ipa_bmp_draw(wmfAPI *API, wmfBMP_Draw_t *bmp_draw)
   MagickWand
     *magick_wand;
 
-  MagickRealType
+  double
     height,
     width;
 
-  PixelPacket
+  PixelInfo
     white;
 
   if (bmp_draw->bmp.data == 0)
     return;
 
-  GetExceptionInfo(&exception);
   image = (Image*)bmp_draw->bmp.data;
   if (!image)
-    {
-       InheritException(&ddata->image->exception,&exception);
-       return;
-    }
+     return;
 
+  exception=ddata->exception;
   if (bmp_draw->crop.x || bmp_draw->crop.y ||
      (bmp_draw->crop.w != bmp_draw->bmp.width) ||
      (bmp_draw->crop.h != bmp_draw->bmp.height))
@@ -524,32 +679,27 @@ static void ipa_bmp_draw(wmfAPI *API, wmfBMP_Draw_t *bmp_draw)
       crop_info.width = bmp_draw->crop.w;
       crop_info.height = bmp_draw->crop.h;
 
-      crop_image = CropImage( image, &crop_info, &exception );
+      crop_image = CropImage( image, &crop_info, exception );
       if (crop_image)
         {
           image=DestroyImageList(image);
           image = crop_image;
           bmp_draw->bmp.data = (void*)image;
         }
-      else
-        InheritException(&ddata->image->exception,&exception);
     }
 
-  QueryColorDatabase( "white", &white, &exception );
+  QueryColorCompliance( "white", AllCompliance, &white, exception );
 
   if ( ddata->image_info->texture ||
-       !(IsColorEqual(&ddata->image_info->background_color,&white)) ||
-       ddata->image_info->background_color.opacity != OpaqueOpacity )
+       !(IsPixelInfoEquivalent(&ddata->image_info->background_color,&white)) ||
+       ddata->image_info->background_color.alpha != OpaqueAlpha )
   {
-    MagickPixelPacket
-      white;
-
     /*
       Set image white background to transparent so that it may be
       overlaid over non-white backgrounds.
     */
-    QueryMagickColor( "white", &white, &exception );
-    TransparentPaintImage( image, &white, QuantumRange, MagickFalse );
+    QueryColorCompliance( "white", AllCompliance, &white, exception );
+    TransparentPaintImage( image, &white, QuantumRange, MagickFalse, exception );
   }
 
   width = fabs(bmp_draw->pixel_width * (double) bmp_draw->crop.w);
@@ -577,7 +727,7 @@ static void ipa_bmp_read(wmfAPI * API, wmfBMP_Read_t * bmp_read) {
     *ddata = WMF_MAGICK_GetData(API);
 
   ExceptionInfo
-    exception;
+    *exception;
 
   Image
     *image;
@@ -587,16 +737,15 @@ static void ipa_bmp_read(wmfAPI * API, wmfBMP_Read_t * bmp_read) {
 
   bmp_read->bmp.data = 0;
 
-  GetExceptionInfo(&exception);
-
-  image_info=CloneImageInfo((ImageInfo *) 0);
+  image_info=CloneImageInfo(ddata->image_info);
+  exception=ddata->exception;
   (void) CopyMagickString(image_info->magick,"DIB",MaxTextExtent);
   if (bmp_read->width || bmp_read->height)
     {
       char
         size[MaxTextExtent];
 
-      (void) FormatMagickString(size,MaxTextExtent,"%ux%u",bmp_read->width,
+      (void) FormatLocaleString(size,MaxTextExtent,"%ux%u",bmp_read->width,
         bmp_read->height);
       CloneString(&image_info->size,size);
     }
@@ -606,19 +755,9 @@ static void ipa_bmp_read(wmfAPI * API, wmfBMP_Read_t * bmp_read) {
    bmp_read->width, bmp_read->height);
 #endif
   image=BlobToImage(image_info, (const void *) bmp_read->buffer,
-    bmp_read->length, &exception);
+    bmp_read->length, exception);
   image_info=DestroyImageInfo(image_info);
-  if (image == (Image *) NULL)
-    {
-      char
-        description[MaxTextExtent];
-
-      (void) FormatMagickString(description,MaxTextExtent,
-        "packed DIB at offset %ld",bmp_read->offset);
-      (void) ThrowMagickException(&ddata->image->exception,GetMagickModule(),
-        CorruptImageError,exception.reason,"`%s'",exception.description);
-    }
-  else
+  if (image != (Image *) NULL)
     {
 #if 0
       printf("ipa_bmp_read: rows=%ld,columns=%ld\n\n", image->rows, image->columns);
@@ -685,8 +824,8 @@ static void ipa_device_begin(wmfAPI * API)
 
   DrawSetViewbox(WmfDrawingWand, 0, 0, ddata->image->columns, ddata->image->rows );
 
-  (void) FormatMagickString(comment,MaxTextExtent,"Created by ImageMagick %s",
-    GetMagickVersion((unsigned long *) NULL));
+  (void) FormatLocaleString(comment,MaxTextExtent,"Created by ImageMagick %s",
+    GetMagickVersion((size_t *) NULL));
   DrawComment(WmfDrawingWand,comment);
 
   /* Scale width and height to image */
@@ -705,7 +844,7 @@ static void ipa_device_begin(wmfAPI * API)
 
       /* Draw rectangle in background color */
       background_color=NewPixelWand();
-      PixelSetQuantumColor(background_color,&ddata->image->background_color);
+      PixelSetPixelColor(background_color,&ddata->image->background_color);
       DrawSetFillColor(WmfDrawingWand,background_color);
       background_color=DestroyPixelWand(background_color);
       DrawRectangle(WmfDrawingWand,
@@ -751,21 +890,19 @@ static void ipa_device_begin(wmfAPI * API)
           magick_wand=DestroyMagickWand(magick_wand);
           (void) DrawPopPattern(WmfDrawingWand);
           DrawPopDefs(WmfDrawingWand);
-          (void) FormatMagickString(pattern_id,MaxTextExtent,"#brush_%lu",
+          (void) FormatLocaleString(pattern_id,MaxTextExtent,"#brush_%lu",
             ddata->pattern_id);
           (void) DrawSetFillPatternURL(WmfDrawingWand,pattern_id);
           ++ddata->pattern_id;
-
           DrawRectangle(WmfDrawingWand,
-                         XC(ddata->bbox.TL.x),YC(ddata->bbox.TL.y),
-                         XC(ddata->bbox.BR.x),YC(ddata->bbox.BR.y));
+            XC(ddata->bbox.TL.x),YC(ddata->bbox.TL.y),
+            XC(ddata->bbox.BR.x),YC(ddata->bbox.BR.y));
           image=DestroyImageList(image);
         }
       else
         {
           LogMagickEvent(CoderEvent,GetMagickModule(),
             "reading texture image failed!");
-          InheritException(&ddata->image->exception,&exception);
         }
     }
 
@@ -943,7 +1080,7 @@ static void util_draw_arc(wmfAPI * API,
       else if (finish == magick_arc_pie)
         {
           DrawPathStart(WmfDrawingWand);
-          DrawPathMoveToAbsolute(WmfDrawingWand, XC(O.x+start.x), 
+          DrawPathMoveToAbsolute(WmfDrawingWand, XC(O.x+start.x),
             YC(O.y+start.y));
           DrawPathEllipticArcAbsolute(WmfDrawingWand, Rx, Ry, 0, MagickFalse,
             MagickTrue, XC(O.x+end.x), YC(O.y+end.y));
@@ -955,7 +1092,7 @@ static void util_draw_arc(wmfAPI * API,
         {
           DrawArc(WmfDrawingWand, XC(draw_arc->TL.x), YC(draw_arc->TL.y),
             XC(draw_arc->BR.x), XC(draw_arc->BR.y), phi_s, phi_e);
-          DrawLine(WmfDrawingWand, XC(draw_arc->BR.x-start.x), 
+          DrawLine(WmfDrawingWand, XC(draw_arc->BR.x-start.x),
             YC(draw_arc->BR.y-start.y), XC(draw_arc->BR.x-end.x),
             YC(draw_arc->BR.y-end.y));
         }
@@ -1199,7 +1336,7 @@ static void ipa_region_clip(wmfAPI *API, wmfPolyRectangle_t *poly_rect)
       /* Define clip path */
       ddata->clip_mask_id++;
       DrawPushDefs(WmfDrawingWand);
-      (void) FormatMagickString(clip_mask_id,MaxTextExtent,"clip_%lu",
+      (void) FormatLocaleString(clip_mask_id,MaxTextExtent,"clip_%lu",
         ddata->clip_mask_id);
       DrawPushClipPath(WmfDrawingWand,clip_mask_id);
       (void) PushDrawingWand(WmfDrawingWand);
@@ -1286,6 +1423,9 @@ static void ipa_draw_text(wmfAPI * API, wmfDrawText_t * draw_text)
     bbox_width,      /* bounding box width */
     pointsize = 0;    /* pointsize to output font with desired height */
 
+  ExceptionInfo
+    *exception;
+
   TypeMetric
     metrics;
 
@@ -1338,11 +1478,14 @@ static void ipa_draw_text(wmfAPI * API, wmfDrawText_t * draw_text)
   font = WMF_DC_FONT(draw_text->dc);
 
   /* Convert font_height to equivalent pointsize */
-  pointsize = util_pointsize( API, font, draw_text->str, draw_text->font_height);
+  exception=ddata->exception;
+  pointsize = util_pointsize( API, font, draw_text->str, draw_text->font_height, exception);
 
   /* Save graphic wand */
   (void) PushDrawingWand(WmfDrawingWand);
 
+  (void) bbox_width;
+  (void) bbox_height;
 #if 0
   printf("\nipa_draw_text\n");
   printf("Text                    = \"%s\"\n", draw_text->str);
@@ -1374,7 +1517,7 @@ static void ipa_draw_text(wmfAPI * API, wmfDrawText_t * draw_text)
       draw_info->pointsize = pointsize;
       draw_info->text=draw_text->str;
 
-      if (GetTypeMetrics(image, draw_info, &metrics) != MagickFalse)
+      if (GetTypeMetrics(image, draw_info, &metrics, exception) != MagickFalse)
         {
           /* Center the text if it is not yet centered and should be */
           if ((WMF_DC_TEXTALIGN(draw_text->dc) & TA_CENTER))
@@ -1419,7 +1562,7 @@ static void ipa_draw_text(wmfAPI * API, wmfDrawText_t * draw_text)
           PixelSetRedQuantum(under_color,ScaleCharToQuantum(box->r));
           PixelSetGreenQuantum(under_color,ScaleCharToQuantum(box->g));
           PixelSetBlueQuantum(under_color,ScaleCharToQuantum(box->b));
-          PixelSetOpacityQuantum(under_color,OpaqueOpacity);
+          PixelSetAlphaQuantum(under_color,OpaqueAlpha);
           DrawSetTextUnderColor(WmfDrawingWand,under_color);
           under_color=DestroyPixelWand(under_color);
         }
@@ -1681,7 +1824,7 @@ static void util_set_brush(wmfAPI * API, wmfDC * dc, const BrushApply brush_appl
           char
             pattern_id[30];
 
-          (void) FormatMagickString(pattern_id,MaxTextExtent,"#brush_%lu",
+          (void) FormatLocaleString(pattern_id,MaxTextExtent,"#brush_%lu",
             ddata->pattern_id);
           if (brush_apply == BrushApplyStroke )
             (void) DrawSetStrokePatternURL(WmfDrawingWand,pattern_id);
@@ -1799,9 +1942,8 @@ static void util_set_brush(wmfAPI * API, wmfDC * dc, const BrushApply brush_appl
               char
                 pattern_id[30];
 
-              (void) FormatMagickString(pattern_id,MaxTextExtent,"#brush_%lu",
+              (void) FormatLocaleString(pattern_id,MaxTextExtent,"#brush_%lu",
                 ddata->pattern_id);
-
               if ( brush_apply == BrushApplyStroke )
                 (void) DrawSetStrokePatternURL(WmfDrawingWand,pattern_id);
               else
@@ -1874,6 +2016,7 @@ static void util_set_pen(wmfAPI * API, wmfDC * dc)
 
   pen_style = (unsigned int) WMF_PEN_STYLE(pen);
   pen_type = (unsigned int) WMF_PEN_TYPE(pen);
+  (void) pen_type;
 
   /* Pen style specified? */
   if (pen_style == PS_NULL)
@@ -1996,7 +2139,7 @@ static void util_set_pen(wmfAPI * API, wmfDC * dc)
 }
 
 /* Estimate font pointsize based on Windows font parameters */
-static double util_pointsize( wmfAPI* API, wmfFont* font, char* str, double font_height)
+static double util_pointsize( wmfAPI* API, wmfFont* font, char* str, double font_height, ExceptionInfo *exception)
 {
   wmf_magick_t
     *ddata = WMF_MAGICK_GetData(API);
@@ -2021,7 +2164,7 @@ static double util_pointsize( wmfAPI* API, wmfFont* font, char* str, double font
   draw_info->pointsize=font_height;
   draw_info->text=str;
 
-  if (GetTypeMetrics(image, draw_info, &metrics) != MagickFalse)
+  if (GetTypeMetrics(image, draw_info, &metrics, exception) != MagickFalse)
     {
 
       if (strlen(str) == 1)
@@ -2029,20 +2172,20 @@ static double util_pointsize( wmfAPI* API, wmfFont* font, char* str, double font
           pointsize = (font_height *
                        ( font_height / (metrics.ascent + fabs(metrics.descent))));
           draw_info->pointsize = pointsize;
-          if (GetTypeMetrics(image, draw_info, &metrics) != MagickFalse)
+          if (GetTypeMetrics(image, draw_info, &metrics, exception) != MagickFalse)
             pointsize *= (font_height / ( metrics.ascent + fabs(metrics.descent)));
         }
       else
         {
           pointsize = (font_height * (font_height / (metrics.height)));
           draw_info->pointsize = pointsize;
-          if (GetTypeMetrics(image, draw_info, &metrics) != MagickFalse)
+          if (GetTypeMetrics(image, draw_info, &metrics, exception) != MagickFalse)
             pointsize *= (font_height / metrics.height);
 
         }
 #if 0
       draw_info.pointsize = pointsize;
-      if (GetTypeMetrics(image, &draw_info, &metrics) != MagickFalse)
+      if (GetTypeMetrics(image, &draw_info, &metrics, exception) != MagickFalse)
         pointsize *= (font_height / (metrics.ascent + fabs(metrics.descent)));
       pointsize *= 1.114286; /* Magic number computed through trial and error */
 #endif
@@ -2108,6 +2251,7 @@ static int util_font_weight( const char* font )
  */
 static float lite_font_stringwidth( wmfAPI* API, wmfFont* font, char* str)
 {
+#if 0
   wmf_magick_t
     *ddata = WMF_MAGICK_GetData(API);
 
@@ -2117,6 +2261,9 @@ static float lite_font_stringwidth( wmfAPI* API, wmfFont* font, char* str)
   DrawInfo
     *draw_info;
 
+  ExceptionInfo
+    *exception;
+
   TypeMetric
     metrics;
 
@@ -2130,8 +2277,8 @@ static float lite_font_stringwidth( wmfAPI* API, wmfFont* font, char* str)
   ResolutionType
     orig_resolution_units;
 
-  orig_x_resolution = image->x_resolution;
-  orig_y_resolution = image->y_resolution;
+  orig_x_resolution = image->resolution.x;
+  orig_y_resolution = image->resolution.y;
   orig_resolution_units = image->units;
 
   draw_info=ddata->draw_info;
@@ -2142,12 +2289,13 @@ static float lite_font_stringwidth( wmfAPI* API, wmfFont* font, char* str)
   draw_info->pointsize=12;
   draw_info->text=str;
 
-  image->x_resolution = 72;
-  image->y_resolution = 72;
+  image->resolution.x = 72;
+  image->resolution.y = 72;
   image->units = PixelsPerInchResolution;
 
-  if (GetTypeMetrics(image, draw_info, &metrics) != MagickFalse)
-    stringwidth = ((metrics.width * 72)/(image->x_resolution * draw_info->pointsize)); /* *0.916348; */
+  exception=ddata->exception;
+  if (GetTypeMetrics(image, draw_info, &metrics, exception) != MagickFalse)
+    stringwidth = ((metrics.width * 72)/(image->resolution.x * draw_info->pointsize)); /* *0.916348; */
 
   draw_info->font=NULL;
   draw_info->text=NULL;
@@ -2163,23 +2311,51 @@ static float lite_font_stringwidth( wmfAPI* API, wmfFont* font, char* str)
   fflush(stdout);
 #endif
 
-  image->x_resolution = orig_x_resolution;
-  image->y_resolution = orig_y_resolution;
+  image->resolution.x = orig_x_resolution;
+  image->resolution.y = orig_y_resolution;
   image->units = orig_resolution_units;
 
   return stringwidth;
+#else
+  (void) API;
+  (void) font;
+  (void) str;
+
+  return 0;
+#endif
 }
 
 /* Map font (similar to wmf_ipa_font_map) */
 
 /* Mappings to Postscript fonts: family, normal, italic, bold, bolditalic */
 static wmfFontMap WMFFontMap[] = {
-  { (char *) "Courier",            (char *) "Courier",     (char *) "Courier-Oblique",   (char *) "Courier-Bold", (char *) "Courier-BoldOblique"   },   { (char *) "Helvetica",          (char *) "Helvetica",   (char *) "Helvetica-Oblique", (char *) "Helvetica-Bold", (char *) "Helvetica-BoldOblique" },   { (char *) "Modern",             (char *) "Courier",     (char *) "Courier-Oblique",   (char *) "Courier-Bold", (char *) "Courier-BoldOblique"   },   { (char *) "Monotype Corsiva",   (char *) "Courier",     (char *) "Courier-Oblique",   (char *) "Courier-Bold", (char *) "Courier-BoldOblique"   },
-  { (char *) "News Gothic",        (char *) "Helvetica",   (char *) "Helvetica-Oblique", (char *) "Helvetica-Bold", (char *) "Helvetica-BoldOblique" },
-  { (char *) "Symbol",             (char *) "Symbol",      (char *) "Symbol",            (char *) "Symbol", (char *) "Symbol"                },
-  { (char *) "System",             (char *) "Courier",     (char *) "Courier-Oblique",   (char *) "Courier-Bold", (char *) "Courier-BoldOblique"   },
-  { (char *) "Times",              (char *) "Times-Roman", (char *) "Times-Italic",      (char *) "Times-Bold", (char *) "Times-BoldItalic"      },
-  {  (char *) NULL,                (char *) NULL,           (char *) NULL,               (char *) NULL,  (char *) NULL                   }
+  { (char *) "Courier",            (char *) "Courier",
+    (char *) "Courier-Oblique",    (char *) "Courier-Bold",
+    (char *) "Courier-BoldOblique"   },
+  { (char *) "Helvetica",          (char *) "Helvetica",
+    (char *) "Helvetica-Oblique",  (char *) "Helvetica-Bold",
+    (char *) "Helvetica-BoldOblique" },
+  { (char *) "Modern",             (char *) "Courier",
+    (char *) "Courier-Oblique",    (char *) "Courier-Bold",
+    (char *) "Courier-BoldOblique"   },
+  { (char *) "Monotype Corsiva",   (char *) "Courier",
+    (char *) "Courier-Oblique",    (char *) "Courier-Bold",
+    (char *) "Courier-BoldOblique"   },
+  { (char *) "News Gothic",        (char *) "Helvetica",
+    (char *) "Helvetica-Oblique",  (char *) "Helvetica-Bold",
+    (char *) "Helvetica-BoldOblique" },
+  { (char *) "Symbol",             (char *) "Symbol",
+    (char *) "Symbol",             (char *) "Symbol",
+    (char *) "Symbol"                },
+  { (char *) "System",             (char *) "Courier",
+    (char *) "Courier-Oblique",    (char *) "Courier-Bold",
+    (char *) "Courier-BoldOblique"   },
+  { (char *) "Times",              (char *) "Times-Roman",
+    (char *) "Times-Italic",       (char *) "Times-Bold",
+    (char *) "Times-BoldItalic"      },
+  { (char *) NULL,                 (char *) NULL,
+    (char *) NULL,                 (char *) NULL,
+    (char *) NULL                   }
 };
 
 
@@ -2210,7 +2386,7 @@ static void lite_font_map( wmfAPI* API, wmfFont* font)
     *ddata = WMF_MAGICK_GetData(API);
 
   ExceptionInfo
-    exception;
+    *exception;
 
   const TypeInfo
     *type_info,
@@ -2230,13 +2406,10 @@ static void lite_font_map( wmfAPI* API, wmfFont* font)
   if (magick_font->ps_name != (char *) NULL)
     magick_font->ps_name=DestroyString(magick_font->ps_name);
 
-  GetExceptionInfo(&exception);
-  type_info_base=GetTypeInfo("*",&exception);
+  exception=ddata->exception;
+  type_info_base=GetTypeInfo("*",exception);
   if (type_info_base == 0)
-    {
-      InheritException(&ddata->image->exception,&exception);
-      return;
-    }
+     return;
 
   /* Certain short-hand font names are not the proper Windows names
      and should be promoted to the proper names */
@@ -2256,10 +2429,10 @@ static void lite_font_map( wmfAPI* API, wmfFont* font)
       else
         target_weight = WMF_FONT_WEIGHT(font);
       type_info=GetTypeInfoByFamily(wmf_font_name,AnyStyle,AnyStretch,
-        target_weight,&exception);
+        target_weight,exception);
       if (type_info == (const TypeInfo *) NULL)
         type_info=GetTypeInfoByFamily(wmf_font_name,AnyStyle,AnyStretch,0,
-          &exception);
+          exception);
       if (type_info != (const TypeInfo *) NULL)
         CloneString(&magick_font->ps_name,type_info->name);
     }
@@ -2375,15 +2548,8 @@ static long ipa_blob_tell(void* wand)
   return (long)TellBlob((Image*)wand);
 }
 
-static Image *ReadWMFImage(const ImageInfo * image_info, ExceptionInfo * exception)
+static Image *ReadWMFImage(const ImageInfo *image_info,ExceptionInfo *exception)
 {
-  Image
-    *image;
-
-  float
-    wmf_width,
-    wmf_height;
-
   double
     bounding_height,
     bounding_width,
@@ -2395,6 +2561,13 @@ static Image *ReadWMFImage(const ImageInfo * image_info, ExceptionInfo * excepti
     resolution_x,
     units_per_inch;
 
+  float
+    wmf_width,
+    wmf_height;
+
+  Image
+    *image;
+
   unsigned long
     wmf_options_flags = 0;
 
@@ -2413,7 +2586,7 @@ static Image *ReadWMFImage(const ImageInfo * image_info, ExceptionInfo * excepti
   wmfD_Rect
     bbox;
 
-  image = AcquireImage(image_info);
+  image=AcquireImage(image_info,exception);
   if (OpenBlob(image_info,image,ReadBinaryBlobMode,exception) == MagickFalse)
     {
       if (image->debug != MagickFalse)
@@ -2458,13 +2631,15 @@ static Image *ReadWMFImage(const ImageInfo * image_info, ExceptionInfo * excepti
   /* Register progress monitor */
   wmf_status_function(API,image,magick_progress_callback);
 
-  ddata = WMF_MAGICK_GetData(API);
-  ddata->image = image;
-  ddata->image_info = image_info;
-  ddata->draw_info = CloneDrawInfo((const ImageInfo *) NULL, (const DrawInfo *) NULL);
-  RelinquishMagickMemory(ddata->draw_info->font);
-  RelinquishMagickMemory(ddata->draw_info->text);
-
+  ddata=WMF_MAGICK_GetData(API);
+  ddata->image=image;
+  ddata->image_info=image_info;
+  ddata->draw_info=CloneDrawInfo(image_info,(const DrawInfo *) NULL);
+  ddata->exception=exception;
+  ddata->draw_info->font=(char *)
+    RelinquishMagickMemory(ddata->draw_info->font);
+  ddata->draw_info->text=(char *)
+    RelinquishMagickMemory(ddata->draw_info->text);
 
 #if defined(MAGICKCORE_WMFLITE_DELEGATE)
   /* Must initialize font subystem for WMFlite interface */
@@ -2478,7 +2653,7 @@ static Image *ReadWMFImage(const ImageInfo * image_info, ExceptionInfo * excepti
    *
    */
   wmf_error = wmf_bbuf_input(API,ipa_blob_read,ipa_blob_seek,
-                             ipa_blob_tell,(void*)image);
+    ipa_blob_tell,(void*)image);
   if (wmf_error != wmf_E_None)
     {
       wmf_api_destroy(API);
@@ -2502,7 +2677,7 @@ static Image *ReadWMFImage(const ImageInfo * image_info, ExceptionInfo * excepti
   if (image->debug != MagickFalse)
     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
       "  Scanning WMF to obtain bounding box");
-  wmf_error = wmf_scan(API, 0, &bbox);
+  wmf_error=wmf_scan(API, 0, &bbox);
   if (wmf_error != wmf_E_None)
     {
       wmf_api_destroy(API);
@@ -2521,27 +2696,26 @@ static Image *ReadWMFImage(const ImageInfo * image_info, ExceptionInfo * excepti
    *
    */
 
-  ddata->bbox = bbox;
+  ddata->bbox=bbox;
 
   /* User specified resolution */
   resolution_y=DefaultResolution;
-  if (image->y_resolution > 0)
+  if (image->resolution.y != 0.0)
     {
-      resolution_y = image->y_resolution;
+      resolution_y = image->resolution.y;
       if (image->units == PixelsPerCentimeterResolution)
         resolution_y *= CENTIMETERS_PER_INCH;
     }
-
   resolution_x=DefaultResolution;
-  if (image->x_resolution > 0)
+  if (image->resolution.x != 0.0)
     {
-      resolution_x = image->x_resolution;
+      resolution_x = image->resolution.x;
       if (image->units == PixelsPerCentimeterResolution)
         resolution_x *= CENTIMETERS_PER_INCH;
     }
 
   /* Obtain output size expressed in metafile units */
-  wmf_error = wmf_size(API, &wmf_width, &wmf_height);
+  wmf_error=wmf_size(API,&wmf_width,&wmf_height);
   if (wmf_error != wmf_E_None)
     {
       wmf_api_destroy(API);
@@ -2557,11 +2731,11 @@ static Image *ReadWMFImage(const ImageInfo * image_info, ExceptionInfo * excepti
 
   /* Obtain (or guess) metafile units */
   if ((API)->File->placeable)
-    units_per_inch = (API)->File->pmh->Inch;
+    units_per_inch=(API)->File->pmh->Inch;
   else if ( (wmf_width*wmf_height) < 1024*1024)
-    units_per_inch = POINTS_PER_INCH;  /* MM_TEXT */
+    units_per_inch=POINTS_PER_INCH;  /* MM_TEXT */
   else
-    units_per_inch = TWIPS_PER_INCH;  /* MM_TWIPS */
+    units_per_inch=TWIPS_PER_INCH;  /* MM_TWIPS */
 
   /* Calculate image width and height based on specified DPI
      resolution */
@@ -2618,13 +2792,15 @@ static Image *ReadWMFImage(const ImageInfo * image_info, ExceptionInfo * excepti
         "  Bounding Box:                %g,%g %g,%g",
         bbox.TL.x, bbox.TL.y, bbox.BR.x, bbox.BR.y);
       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
-        "  Bounding width x height:     %gx%g",bounding_width,bounding_height);
+        "  Bounding width x height:     %gx%g",bounding_width,
+        bounding_height);
       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
         "  Output resolution:           %gx%g",resolution_x,resolution_y);
       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
         "  Image size:                  %gx%g",image_width,image_height);
       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
-        "  Bounding box scale factor:   %g,%g",ddata->scale_x,ddata->scale_y);
+        "  Bounding box scale factor:   %g,%g",ddata->scale_x,
+        ddata->scale_y);
       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
         "  Translation:                 %g,%g",
         ddata->translate_x, ddata->translate_y);
@@ -2686,36 +2862,17 @@ static Image *ReadWMFImage(const ImageInfo * image_info, ExceptionInfo * excepti
     }
   if (image->debug != MagickFalse)
     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
-       "  Creating canvas image with size %ldx%ld",
-       image->rows,image->columns);
+       "  Creating canvas image with size %lux%lu",(unsigned long) image->rows,
+       (unsigned long) image->columns);
 
   /*
    * Set solid background color
    */
   {
-    unsigned long
-      column,
-      row;
-
-    PixelPacket
-      *pixel,
-      background_color;
-
-    background_color = image_info->background_color;
-    image->background_color = background_color;
-    if (background_color.opacity != OpaqueOpacity)
-      image->matte = MagickTrue;
-
-    for (row=0; row < image->rows; row++)
-      {
-        pixel=QueueAuthenticPixels(image,0,row,image->columns,1,exception);
-        if (pixel == (PixelPacket *) NULL)
-          break;
-        for (column=image->columns; column; column--)
-          *pixel++ = background_color;
-        if (SyncAuthenticPixels(image,exception) == MagickFalse)
-          break;
-      }
+    image->background_color = image_info->background_color;
+    if (image->background_color.alpha != OpaqueAlpha)
+      image->alpha_trait=BlendPixelTrait;
+    (void) SetImageBackgroundColor(image,exception);
   }
   /*
    * Play file to generate Vector drawing commands
@@ -2750,11 +2907,6 @@ static Image *ReadWMFImage(const ImageInfo * image_info, ExceptionInfo * excepti
       "  Rendering WMF vectors");
   DrawRender(ddata->draw_wand);
 
-  /* Check for and report any rendering error */
-  if (image->exception.severity != UndefinedException)
-    (void) ThrowMagickException(exception,GetMagickModule(),CoderWarning,
-      ddata->image->exception.reason,"`%s'",ddata->image->exception.description);
-
   if (image->debug != MagickFalse)
     (void) LogMagickEvent(CoderEvent,GetMagickModule(),"leave ReadWMFImage()");
 
@@ -2765,8 +2917,7 @@ static Image *ReadWMFImage(const ImageInfo * image_info, ExceptionInfo * excepti
   /* Return image */
   return image;
 }
-/* #endif */
-#endif /* MAGICKCORE_WMF_DELEGATE || MAGICKCORE_WMFLITE_DELEGATE */
+#endif
 \f
 /*
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -2788,10 +2939,10 @@ static Image *ReadWMFImage(const ImageInfo * image_info, ExceptionInfo * excepti
 %
 %  The format of the RegisterWMFImage method is:
 %
-%      unsigned long RegisterWMFImage(void)
+%      size_t RegisterWMFImage(void)
 %
 */
-ModuleExport unsigned long RegisterWMFImage(void)
+ModuleExport size_t RegisterWMFImage(void)
 {
   MagickInfo
     *entry;
@@ -2801,17 +2952,14 @@ ModuleExport unsigned long RegisterWMFImage(void)
   entry->decoder=ReadWMFImage;
 #endif
   entry->description=ConstantString("Compressed Windows Meta File");
-  entry->blob_support=MagickTrue;
-  entry->seekable_stream=MagickTrue;
   entry->module=ConstantString("WMZ");
+  entry->seekable_stream=MagickTrue;
   (void) RegisterMagickInfo(entry);
   entry=SetMagickInfo("WMF");
 #if defined(MAGICKCORE_WMF_DELEGATE) || defined(MAGICKCORE_WMFLITE_DELEGATE)
   entry->decoder=ReadWMFImage;
 #endif
   entry->description=ConstantString("Windows Meta File");
-  entry->blob_support=MagickTrue;
-  entry->seekable_stream=MagickTrue;
   entry->module=ConstantString("WMF");
   (void) RegisterMagickInfo(entry);
   return(MagickImageCoderSignature);