]> granicus.if.org Git - imagemagick/blobdiff - coders/wmf.c
https://github.com/ImageMagick/ImageMagick/issues/631
[imagemagick] / coders / wmf.c
index 9d5441ae222d9aa8aa6663d72c8fe6687d746ec9..e5913372b58f1afffbeb77163d0bcef581661c06 100644 (file)
 %                               December 2000                                 %
 %                                                                             %
 %                                                                             %
-%  Copyright 1999-2015 ImageMagick Studio LLC, a non-profit organization      %
+%  Copyright 1999-2017 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                            %
+%    https://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,          %
 #include "MagickWand/MagickWand.h"
 
 #if defined(__CYGWIN__)
-#undef MAGICKCORE_WMF_DELEGATE 
+#undef MAGICKCORE_SANS_DELEGATE
 #endif
 
-#if defined(MAGICKCORE_WMF_DELEGATE)
+#if defined(MAGICKCORE_SANS_DELEGATE)
 #include "libwmf/api.h"
 #include "libwmf/eps.h"
 \f
@@ -116,7 +116,7 @@ static long WMFTellBlob(void *image)
 static Image *ReadWMFImage(const ImageInfo *image_info,ExceptionInfo *exception)
 {
   char
-    filename[MaxTextExtent];
+    filename[MagickPathExtent];
 
   int
     unique_file;
@@ -220,22 +220,22 @@ static Image *ReadWMFImage(const ImageInfo *image_info,ExceptionInfo *exception)
   */
   read_info=CloneImageInfo(image_info);
   SetImageInfoBlob(read_info,(void *) NULL,0);
-  (void) FormatLocaleString(read_info->filename,MaxTextExtent,"eps:%s",
+  (void) FormatLocaleString(read_info->filename,MagickPathExtent,"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);
+        MagickPathExtent);
       (void) CopyMagickString(image->magick_filename,image_info->filename,
-        MaxTextExtent);
-      (void) CopyMagickString(image->magick,"WMF",MaxTextExtent);
+        MagickPathExtent);
+      (void) CopyMagickString(image->magick,"WMF",MagickPathExtent);
     }
   (void) RelinquishUniqueFileResource(filename);
   return(GetFirstImageInList(image));
 }
-#elif defined(MAGICKCORE_WMFLITE_DELEGATE)
+#elif defined(MAGICKCORE_WMF_DELEGATE)
 
 #define ERR(API)  ((API)->err != wmf_E_None)
 #define XC(x) ((double) x)
@@ -300,7 +300,7 @@ static Image *ReadWMFImage(const ImageInfo *image_info,ExceptionInfo *exception)
 #define CENTIMETERS_PER_INCH  2.54
 #define POINTS_PER_INCH       72
 
-#if defined(MAGICKCORE_WMFLITE_DELEGATE)
+#if defined(MAGICKCORE_WMF_DELEGATE)
 # define wmf_api_create(api,flags,options) wmf_lite_create(api,flags,options)
 # define wmf_api_destroy(api) wmf_lite_destroy(api)
 # undef WMF_FONT_PSNAME
@@ -394,7 +394,7 @@ typedef enum
 }
 magick_arc_t;
 
-#if defined(MAGICKCORE_WMFLITE_DELEGATE)
+#if defined(MAGICKCORE_WMF_DELEGATE)
 static void  lite_font_init (wmfAPI* API, wmfAPI_Options* options);
 static void  lite_font_map(wmfAPI* API,wmfFont* font);
 static float lite_font_stringwidth(wmfAPI* API, wmfFont* font, char* str);
@@ -420,7 +420,7 @@ static void         ipa_draw_line(wmfAPI * API, wmfDrawLine_t * draw_line);
 static void         ipa_draw_pie(wmfAPI * API, wmfDrawArc_t * draw_arc);
 static void         ipa_draw_pixel(wmfAPI * API, wmfDrawPixel_t * draw_pixel);
 static void         ipa_draw_polygon(wmfAPI * API, wmfPolyLine_t * poly_line);
-#if defined(MAGICKCORE_WMFLITE_DELEGATE)
+#if defined(MAGICKCORE_WMF_DELEGATE)
 static void         ipa_draw_polypolygon(wmfAPI * API, wmfPolyPoly_t* polypolygon);
 #endif
 static void         ipa_draw_rectangle(wmfAPI * API, wmfDrawRectangle_t * draw_rect);
@@ -439,7 +439,7 @@ static void         ipa_udata_init(wmfAPI * API, wmfUserData_t * userdata);
 static void         ipa_udata_set(wmfAPI * API, wmfUserData_t * userdata);
 static int          magick_progress_callback(void* wand,float quantum);
 static void         util_draw_arc(wmfAPI * API, wmfDrawArc_t * draw_arc,magick_arc_t finish);
-#if defined(MAGICKCORE_WMFLITE_DELEGATE)
+#if defined(MAGICKCORE_WMF_DELEGATE)
 /*static int          util_font_weight( const char* font );*/
 #endif
 static double       util_pointsize( wmfAPI* API, wmfFont* font, char* str, double font_height, ExceptionInfo *);
@@ -457,7 +457,7 @@ int magick_progress_callback(void *context,float quantum)
 
   (void) quantum;
   image=(Image *) context;
-  assert(image->signature == MagickSignature);
+  assert(image->signature == MagickCoreSignature);
   status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
     GetBlobSize(image));
   return(status != MagickFalse ? 0 : 1);
@@ -532,9 +532,9 @@ static void draw_pattern_push( wmfAPI* API,
                                unsigned long rows )
 {
   char
-    pattern_id[30];
+    pattern_id[MagickPathExtent];
 
-  (void) FormatLocaleString(pattern_id,MaxTextExtent,"brush_%lu",id);
+  (void) FormatLocaleString(pattern_id,MagickPathExtent,"brush_%lu",id);
   (void) DrawPushPattern(WmfDrawingWand,pattern_id,0,0,columns,rows);
 }
 
@@ -744,13 +744,13 @@ static void ipa_bmp_read(wmfAPI * API, wmfBMP_Read_t * bmp_read) {
 
   image_info=CloneImageInfo(ddata->image_info);
   exception=ddata->exception;
-  (void) CopyMagickString(image_info->magick,"DIB",MaxTextExtent);
+  (void) CopyMagickString(image_info->magick,"DIB",MagickPathExtent);
   if (bmp_read->width || bmp_read->height)
     {
       char
-        size[MaxTextExtent];
+        size[MagickPathExtent];
 
-      (void) FormatLocaleString(size,MaxTextExtent,"%ux%u",bmp_read->width,
+      (void) FormatLocaleString(size,MagickPathExtent,"%ux%u",bmp_read->width,
         bmp_read->height);
       CloneString(&image_info->size,size);
     }
@@ -797,7 +797,7 @@ static void ipa_device_open(wmfAPI * API)
 
   ddata->push_depth = 0;
 
-  ddata->draw_wand = DrawAllocateWand(ddata->draw_info,ddata->image);
+  ddata->draw_wand = AcquireDrawingWand(ddata->draw_info,ddata->image);
 }
 
 /*
@@ -818,7 +818,9 @@ static void ipa_device_close(wmfAPI * API)
       DestroyDrawInfo(ddata->draw_info);
       ddata->draw_info=(DrawInfo *)NULL;
     }
-  RelinquishMagickMemory(WMF_MAGICK_GetFontData(API)->ps_name);
+  if (WMF_MAGICK_GetFontData(API)->ps_name)
+    WMF_MAGICK_GetFontData(API)->ps_name=RelinquishMagickMemory(
+      WMF_MAGICK_GetFontData(API)->ps_name);
 }
 
 /*
@@ -827,7 +829,8 @@ static void ipa_device_close(wmfAPI * API)
 static void ipa_device_begin(wmfAPI * API)
 {
   char
-    comment[MaxTextExtent];
+    comment[MagickPathExtent],
+    *url;
 
   wmf_magick_t
     *ddata = WMF_MAGICK_GetData(API);
@@ -835,10 +838,12 @@ static void ipa_device_begin(wmfAPI * API)
   /* Make SVG output happy */
   (void) PushDrawingWand(WmfDrawingWand);
 
-  DrawSetViewbox(WmfDrawingWand, 0, 0, ddata->image->columns, ddata->image->rows );
+  DrawSetViewbox(WmfDrawingWand,0,0,ddata->image->columns,ddata->image->rows);
 
-  (void) FormatLocaleString(comment,MaxTextExtent,"Created by ImageMagick %s",
-    GetMagickVersion((size_t *) NULL));
+  url=GetMagickHomeURL();
+  (void) FormatLocaleString(comment,MagickPathExtent,
+    "Created by ImageMagick %s",url);
+  url=DestroyString(url);
   DrawComment(WmfDrawingWand,comment);
 
   /* Scale width and height to image */
@@ -880,7 +885,7 @@ static void ipa_device_begin(wmfAPI * API)
 
       image_info = CloneImageInfo((ImageInfo *) 0);
       (void) CopyMagickString(image_info->filename,ddata->image_info->texture,
-        MaxTextExtent);
+        MagickPathExtent);
       if ( ddata->image_info->size )
         CloneString(&image_info->size,ddata->image_info->size);
 
@@ -890,12 +895,12 @@ static void ipa_device_begin(wmfAPI * API)
       if (image)
         {
           char
-            pattern_id[30];
+            pattern_id[MagickPathExtent];
 
           MagickWand
             *magick_wand;
 
-          (void) CopyMagickString(image->magick,"MIFF",MaxTextExtent);
+          (void) CopyMagickString(image->magick,"MIFF",MagickPathExtent);
           DrawPushDefs(WmfDrawingWand);
           draw_pattern_push(API,ddata->pattern_id,image->columns,image->rows);
           magick_wand=NewMagickWandFromImage(image);
@@ -904,7 +909,7 @@ static void ipa_device_begin(wmfAPI * API)
           magick_wand=DestroyMagickWand(magick_wand);
           (void) DrawPopPattern(WmfDrawingWand);
           DrawPopDefs(WmfDrawingWand);
-          (void) FormatLocaleString(pattern_id,MaxTextExtent,"#brush_%lu",
+          (void) FormatLocaleString(pattern_id,MagickPathExtent,"#brush_%lu",
             ddata->pattern_id);
           (void) DrawSetFillPatternURL(WmfDrawingWand,pattern_id);
           ++ddata->pattern_id;
@@ -1203,7 +1208,7 @@ static void ipa_draw_polygon(wmfAPI * API, wmfPolyLine_t * polyline)
 }
 
 /* Draw a polypolygon.  A polypolygon is a list of polygons */
-#if defined(MAGICKCORE_WMFLITE_DELEGATE)
+#if defined(MAGICKCORE_WMF_DELEGATE)
 static void ipa_draw_polypolygon(wmfAPI * API, wmfPolyPoly_t* polypolygon)
 {
   if (TO_FILL(polypolygon) || TO_DRAW(polypolygon))
@@ -1345,12 +1350,12 @@ static void ipa_region_clip(wmfAPI *API, wmfPolyRectangle_t *poly_rect)
   if (poly_rect->count > 0)
     {
       char
-        clip_mask_id[30];
+        clip_mask_id[MagickPathExtent];
 
       /* Define clip path */
       ddata->clip_mask_id++;
       DrawPushDefs(WmfDrawingWand);
-      (void) FormatLocaleString(clip_mask_id,MaxTextExtent,"clip_%lu",
+      (void) FormatLocaleString(clip_mask_id,MagickPathExtent,"clip_%lu",
         ddata->clip_mask_id);
       DrawPushClipPath(WmfDrawingWand,clip_mask_id);
       (void) PushDrawingWand(WmfDrawingWand);
@@ -1396,7 +1401,7 @@ static void ipa_functions(wmfAPI *API)
   FR->draw_line = ipa_draw_line;
   FR->poly_line = ipa_poly_line;
   FR->draw_polygon = ipa_draw_polygon;
-#if defined(MAGICKCORE_WMFLITE_DELEGATE)
+#if defined(MAGICKCORE_WMF_DELEGATE)
   FR->draw_polypolygon = ipa_draw_polypolygon;
 #endif
   FR->draw_rectangle = ipa_draw_rectangle;
@@ -1539,7 +1544,7 @@ static void ipa_draw_text(wmfAPI * API, wmfDrawText_t * draw_text)
               double
                 text_width = metrics.width * (ddata->scale_y / ddata->scale_x);
 
-#if defined(MAGICKCORE_WMFLITE_DELEGATE)
+#if defined(MAGICKCORE_WMF_DELEGATE)
               point.x -= text_width / 2;
 #else
               point.x += bbox_width / 2 - text_width / 2;
@@ -1829,9 +1834,9 @@ static void util_set_brush(wmfAPI *API, wmfDC *dc,const BrushApply brush_apply)
         DrawPopDefs(WmfDrawingWand);
         {
           char
-            pattern_id[30];
+            pattern_id[MagickPathExtent];
 
-          (void) FormatLocaleString(pattern_id,MaxTextExtent,"#brush_%lu",
+          (void) FormatLocaleString(pattern_id,MagickPathExtent,"#brush_%lu",
             ddata->pattern_id);
           if (brush_apply == BrushApplyStroke )
             (void) DrawSetStrokePatternURL(WmfDrawingWand,pattern_id);
@@ -1942,9 +1947,9 @@ static void util_set_brush(wmfAPI *API, wmfDC *dc,const BrushApply brush_apply)
 
             {
               char
-                pattern_id[30];
+                pattern_id[MagickPathExtent];
 
-              (void) FormatLocaleString(pattern_id,MaxTextExtent,"#brush_%lu",
+              (void) FormatLocaleString(pattern_id,MagickPathExtent,"#brush_%lu",
                 ddata->pattern_id);
               if ( brush_apply == BrushApplyStroke )
                 (void) DrawSetStrokePatternURL(WmfDrawingWand,pattern_id);
@@ -1994,8 +1999,7 @@ static void util_set_pen(wmfAPI * API, wmfDC * dc)
     pixel_width;
 
   unsigned int
-    pen_style,
-    pen_type;
+    pen_style;
 
   pen = WMF_DC_PEN(dc);
 
@@ -2010,8 +2014,6 @@ static void util_set_pen(wmfAPI * API, wmfDC * dc)
   pen_width = MagickMax(pen_width, pixel_width*0.8);
 
   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)
@@ -2203,7 +2205,7 @@ static double util_pointsize( wmfAPI* API, wmfFont* font, char* str, double font
   return floor(pointsize);
 }
 
-#if defined(MAGICKCORE_WMFLITE_DELEGATE)
+#if defined(MAGICKCORE_WMF_DELEGATE)
 /* Estimate weight based on font name */
 /*
 static int util_font_weight( const char* font )
@@ -2436,7 +2438,7 @@ static void lite_font_map( wmfAPI* API, wmfFont* font)
   if (!magick_font->ps_name)
     {
       char
-        target[MaxTextExtent];
+        target[MagickPathExtent];
 
       int
         target_weight = 400,
@@ -2456,13 +2458,13 @@ static void lite_font_map( wmfAPI* API, wmfFont* font)
                                        strstr(wmf_font_name,"Oblique"))) )
         want_italic = MagickTrue;
 
-      (void) CopyMagickString(target,"Times",MaxTextExtent);
+      (void) CopyMagickString(target,"Times",MagickPathExtent);
       for( i=0; SubFontMap[i].name != NULL; i++ )
         {
           if (LocaleCompare(wmf_font_name, SubFontMap[i].name) == 0)
             {
               (void) CopyMagickString(target,SubFontMap[i].mapping,
-                MaxTextExtent);
+                MagickPathExtent);
               break;
             }
         }
@@ -2523,7 +2525,7 @@ static void lite_font_init( wmfAPI* API, wmfAPI_Options* options)
   ((wmf_magick_font_t*)font_data->user_data)->pointsize = 0;
 }
 
-#endif /* MAGICKCORE_WMFLITE_DELEGATE */
+#endif /* MAGICKCORE_WMF_DELEGATE */
 
 /* BLOB read byte */
 static int ipa_blob_read(void* wand)
@@ -2614,8 +2616,6 @@ static Image *ReadWMFImage(const ImageInfo *image_info,ExceptionInfo *exception)
   wmf_error = wmf_api_create(&API, wmf_options_flags, &wmf_api_options);
   if (wmf_error != wmf_E_None)
     {
-      if (API)
-        wmf_api_destroy(API);
       if (image->debug != MagickFalse)
         {
           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
@@ -2623,6 +2623,8 @@ static Image *ReadWMFImage(const ImageInfo *image_info,ExceptionInfo *exception)
           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
             "leave ReadWMFImage()");
         }
+      if (API)
+        wmf_api_destroy(API);
       ThrowReaderException(DelegateError,"UnableToInitializeWMFLibrary");
     }
 
@@ -2639,7 +2641,7 @@ static Image *ReadWMFImage(const ImageInfo *image_info,ExceptionInfo *exception)
   ddata->draw_info->text=(char *)
     RelinquishMagickMemory(ddata->draw_info->text);
 
-#if defined(MAGICKCORE_WMFLITE_DELEGATE)
+#if defined(MAGICKCORE_WMF_DELEGATE)
   /* Must initialize font subystem for WMFlite interface */
   lite_font_init (API,&wmf_api_options); /* similar to wmf_ipa_font_init in src/font.c */
   /* wmf_arg_fontdirs (API,options); */ /* similar to wmf_arg_fontdirs in src/wmf.c */
@@ -2654,7 +2656,6 @@ static Image *ReadWMFImage(const ImageInfo *image_info,ExceptionInfo *exception)
     ipa_blob_tell,(void*)image);
   if (wmf_error != wmf_E_None)
     {
-      wmf_api_destroy(API);
       if (image->debug != MagickFalse)
         {
           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
@@ -2662,6 +2663,7 @@ static Image *ReadWMFImage(const ImageInfo *image_info,ExceptionInfo *exception)
           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
             "leave ReadWMFImage()");
         }
+      wmf_api_destroy(API);
       ThrowFileException(exception,FileOpenError,"UnableToOpenFile",
         image->filename);
       image=DestroyImageList(image);
@@ -2678,7 +2680,6 @@ static Image *ReadWMFImage(const ImageInfo *image_info,ExceptionInfo *exception)
   wmf_error=wmf_scan(API, 0, &bbox);
   if (wmf_error != wmf_E_None)
     {
-      wmf_api_destroy(API);
       if (image->debug != MagickFalse)
         {
           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
@@ -2686,6 +2687,8 @@ static Image *ReadWMFImage(const ImageInfo *image_info,ExceptionInfo *exception)
           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
             "leave ReadWMFImage()");
         }
+      ipa_device_close(API);
+      wmf_api_destroy(API);
       ThrowReaderException(DelegateError,"FailedToScanFile");
     }
 
@@ -2716,7 +2719,6 @@ static Image *ReadWMFImage(const ImageInfo *image_info,ExceptionInfo *exception)
   wmf_error=wmf_size(API,&wmf_width,&wmf_height);
   if (wmf_error != wmf_E_None)
     {
-      wmf_api_destroy(API);
       if (image->debug != MagickFalse)
         {
           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
@@ -2724,6 +2726,7 @@ static Image *ReadWMFImage(const ImageInfo *image_info,ExceptionInfo *exception)
           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
             "leave ReadWMFImage()");
         }
+      wmf_api_destroy(API);
       ThrowReaderException(DelegateError,"FailedToComputeOutputSize");
     }
 
@@ -2830,7 +2833,7 @@ static Image *ReadWMFImage(const ImageInfo *image_info,ExceptionInfo *exception)
     printf("dc->Window.height = %d\n", dc->Window.height);
     printf("dc->pixel_width   = %g\n", dc->pixel_width);
     printf("dc->pixel_height  = %g\n", dc->pixel_height);
-#if defined(MAGICKCORE_WMFLITE_DELEGATE)  /* Only in libwmf 0.3 */
+#if defined(MAGICKCORE_WMF_DELEGATE)  /* Only in libwmf 0.3 */
     printf("dc->Ox            = %.d\n", dc->Ox);
     printf("dc->Oy            = %.d\n", dc->Oy);
     printf("dc->width         = %.d\n", dc->width);
@@ -2887,7 +2890,6 @@ static Image *ReadWMFImage(const ImageInfo *image_info,ExceptionInfo *exception)
   wmf_error = wmf_play(API, 0, &bbox);
   if (wmf_error != wmf_E_None)
     {
-      wmf_api_destroy(API);
       if (image->debug != MagickFalse)
         {
           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
@@ -2895,6 +2897,7 @@ static Image *ReadWMFImage(const ImageInfo *image_info,ExceptionInfo *exception)
           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
             "leave ReadWMFImage()");
         }
+      wmf_api_destroy(API);
       ThrowReaderException(DelegateError,"FailedToRenderFile");
     }
 
@@ -2948,20 +2951,16 @@ ModuleExport size_t RegisterWMFImage(void)
   MagickInfo
     *entry;
 
-  entry = SetMagickInfo("WMZ");
-#if defined(MAGICKCORE_WMF_DELEGATE) || defined(MAGICKCORE_WMFLITE_DELEGATE)
+  entry = AcquireMagickInfo("WMF","WMZ","Compressed Windows Meta File");
+#if defined(MAGICKCORE_SANS_DELEGATE) || defined(MAGICKCORE_WMF_DELEGATE)
   entry->decoder=ReadWMFImage;
 #endif
-  entry->description=ConstantString("Compressed Windows Meta File");
-  entry->module=ConstantString("WMZ");
-  entry->flags|=CoderSeekableStreamFlag;
+  entry->flags|=CoderDecoderSeekableStreamFlag;
   (void) RegisterMagickInfo(entry);
-  entry=SetMagickInfo("WMF");
-#if defined(MAGICKCORE_WMF_DELEGATE) || defined(MAGICKCORE_WMFLITE_DELEGATE)
+  entry=AcquireMagickInfo("WMF","WMF","Windows Meta File");
+#if defined(MAGICKCORE_SANS_DELEGATE) || defined(MAGICKCORE_WMF_DELEGATE)
   entry->decoder=ReadWMFImage;
 #endif
-  entry->description=ConstantString("Windows Meta File");
-  entry->module=ConstantString("WMF");
   (void) RegisterMagickInfo(entry);
   return(MagickImageCoderSignature);
 }