]> granicus.if.org Git - imagemagick/blobdiff - MagickCore/draw.c
(no commit message)
[imagemagick] / MagickCore / draw.c
index f7bc5c58487bdecd9be34564644c7f02b00ed3b2..cb33e7a59e70b7c185f3c56816eb0a70f629c0ba 100644 (file)
 %                                                                             %
 %                                                                             %
 %                              Software Design                                %
-%                                John Cristy                                  %
+%                                   Cristy                                    %
 %                                 July 1998                                   %
 %                                                                             %
 %                                                                             %
-%  Copyright 1999-2013 ImageMagick Studio LLC, a non-profit organization      %
+%  Copyright 1999-2014 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  %
@@ -51,6 +51,7 @@
 #include "MagickCore/blob.h"
 #include "MagickCore/cache.h"
 #include "MagickCore/cache-view.h"
+#include "MagickCore/channel.h"
 #include "MagickCore/color.h"
 #include "MagickCore/colorspace-private.h"
 #include "MagickCore/composite.h"
@@ -548,7 +549,8 @@ static PolygonInfo *ConvertPathToPolygon(
     next_direction=((path_info[i].point.y > point.y) ||
       ((path_info[i].point.y == point.y) &&
        (path_info[i].point.x > point.x))) ? 1 : -1;
-    if ((direction != 0) && (direction != next_direction))
+    if ((points != (PointInfo *) NULL) && (direction != 0) &&
+        (direction != next_direction))
       {
         /*
           New edge.
@@ -1105,11 +1107,6 @@ MagickExport MagickBooleanType DrawAffineImage(Image *image,
   SegmentInfo
     edge;
 
-#if defined(MAGICKCORE_OPENMP_SUPPORT)
-  size_t
-    height;
-#endif
-
   ssize_t
     start,
     stop,
@@ -1166,14 +1163,11 @@ MagickExport MagickBooleanType DrawAffineImage(Image *image,
   GetPixelInfo(image,&zero);
   start=(ssize_t) ceil(edge.y1-0.5);
   stop=(ssize_t) floor(edge.y2+0.5);
-#if defined(MAGICKCORE_OPENMP_SUPPORT)
-  height=(size_t) (floor(edge.y2+0.5)-ceil(edge.y1-0.5));
-#endif
   source_view=AcquireVirtualCacheView(source,exception);
   image_view=AcquireAuthenticCacheView(image,exception);
 #if defined(MAGICKCORE_OPENMP_SUPPORT)
   #pragma omp parallel for schedule(static,4) shared(status) \
-    magick_threads(source,image,height,1)
+    magick_threads(source,image,1,1)
 #endif
   for (y=start; y <= stop; y++)
   {
@@ -1200,8 +1194,8 @@ MagickExport MagickBooleanType DrawAffineImage(Image *image,
     if (inverse_edge.x2 < inverse_edge.x1)
       continue;
     q=GetCacheViewAuthenticPixels(image_view,(ssize_t) ceil(inverse_edge.x1-
-      0.5),y,(size_t) ((ssize_t) floor(inverse_edge.x2+0.5)-(ssize_t) ceil(
-      inverse_edge.x1-0.5)),1,exception);
+      0.5),y,(size_t) (floor(inverse_edge.x2+0.5)-ceil(inverse_edge.x1-0.5)+1),
+      1,exception);
     if (q == (Quantum *) NULL)
       continue;
     pixel=zero;
@@ -1446,7 +1440,7 @@ MagickExport MagickBooleanType DrawClipPath(Image *image,
   status=NegateImage(clip_mask,MagickFalse,exception);
   (void) SetImageMask(image,clip_mask,exception);
   clip_mask=DestroyImage(clip_mask);
-  status=DrawImage(image,clone_info,exception);
+  status&=DrawImage(image,clone_info,exception);
   clone_info=DestroyDrawInfo(clone_info);
   if (image->debug != MagickFalse)
     (void) LogMagickEvent(DrawEvent,GetMagickModule(),"end clip-path");
@@ -1542,7 +1536,7 @@ static MagickBooleanType DrawDashPolygon(const DrawInfo *draw_info,
       {
         offset-=length;
         n++;
-        length=scale*(draw_info->dash_pattern[n]+(n == 0 ? -0.5 : 0.5));
+        length=scale*(draw_info->dash_pattern[n]+0.5);
         continue;
       }
     if (offset < length)
@@ -1594,7 +1588,7 @@ static MagickBooleanType DrawDashPolygon(const DrawInfo *draw_info,
           j++;
           dash_polygon[0].coordinates=(size_t) j;
           dash_polygon[j].primitive=UndefinedPrimitive;
-          status|=DrawStrokePolygon(image,clone_info,dash_polygon,exception);
+          status&=DrawStrokePolygon(image,clone_info,dash_polygon,exception);
         }
       n++;
       if (draw_info->dash_pattern[n] == 0.0)
@@ -1617,7 +1611,7 @@ static MagickBooleanType DrawDashPolygon(const DrawInfo *draw_info,
       j++;
       dash_polygon[0].coordinates=(size_t) j;
       dash_polygon[j].primitive=UndefinedPrimitive;
-      status|=DrawStrokePolygon(image,clone_info,dash_polygon,exception);
+      status&=DrawStrokePolygon(image,clone_info,dash_polygon,exception);
     }
   dash_polygon=(PrimitiveInfo *) RelinquishMagickMemory(dash_polygon);
   clone_info=DestroyDrawInfo(clone_info);
@@ -1702,7 +1696,9 @@ MagickExport MagickBooleanType DrawImage(Image *image,const DrawInfo *draw_info,
     **graphic_context;
 
   MagickBooleanType
-    proceed,
+    proceed;
+
+  MagickStatusType
     status;
 
   double
@@ -1760,7 +1756,7 @@ MagickExport MagickBooleanType DrawImage(Image *image,const DrawInfo *draw_info,
   if (*draw_info->primitive != '@')
     primitive=AcquireString(draw_info->primitive);
   else
-    primitive=FileToString(draw_info->primitive+1,~0,exception);
+    primitive=FileToString(draw_info->primitive+1,~0UL,exception);
   if (primitive == (char *) NULL)
     return(MagickFalse);
   primitive_extent=(double) strlen(primitive);
@@ -1965,6 +1961,20 @@ MagickExport MagickBooleanType DrawImage(Image *image,const DrawInfo *draw_info,
               graphic_context[n]->decorate=(DecorationType) decorate;
             break;
           }
+        if (LocaleCompare("direction",keyword) == 0)
+          {
+            ssize_t
+              direction;
+
+            GetMagickToken(q,&q,token);
+            direction=ParseCommandOption(MagickDirectionOptions,MagickFalse,
+              token);
+            if (direction == -1)
+              status=MagickFalse;
+            else
+              graphic_context[n]->direction=(DirectionType) direction;
+            break;
+          }
         status=MagickFalse;
         break;
       }
@@ -1997,7 +2007,7 @@ MagickExport MagickBooleanType DrawImage(Image *image,const DrawInfo *draw_info,
                 &graphic_context[n]->fill_pattern,exception);
             else
               {
-                status=QueryColorCompliance(token,AllCompliance,
+                status&=QueryColorCompliance(token,AllCompliance,
                   &graphic_context[n]->fill,exception);
                 if (status == MagickFalse)
                   {
@@ -2252,7 +2262,7 @@ MagickExport MagickBooleanType DrawImage(Image *image,const DrawInfo *draw_info,
                 if (n <= 0)
                   {
                     (void) ThrowMagickException(exception,GetMagickModule(),
-                      DrawError,"UnbalancedGraphicContextPushPop","'%s'",token);
+                      DrawError,"UnbalancedGraphicContextPushPop","`%s'",token);
                     n=0;
                     break;
                   }
@@ -2417,7 +2427,7 @@ MagickExport MagickBooleanType DrawImage(Image *image,const DrawInfo *draw_info,
                 if (graphic_context == (DrawInfo **) NULL)
                   {
                     (void) ThrowMagickException(exception,GetMagickModule(),
-                      ResourceLimitError,"MemoryAllocationFailed","'%s'",
+                      ResourceLimitError,"MemoryAllocationFailed","`%s'",
                       image->filename);
                     break;
                   }
@@ -2509,7 +2519,7 @@ MagickExport MagickBooleanType DrawImage(Image *image,const DrawInfo *draw_info,
                 &graphic_context[n]->stroke_pattern,exception);
             else
               {
-                status=QueryColorCompliance(token,AllCompliance,
+                status&=QueryColorCompliance(token,AllCompliance,
                   &graphic_context[n]->stroke,exception);
                 if (status == MagickFalse)
                   {
@@ -2560,7 +2570,7 @@ MagickExport MagickBooleanType DrawImage(Image *image,const DrawInfo *draw_info,
                 if (graphic_context[n]->dash_pattern == (double *) NULL)
                   {
                     (void) ThrowMagickException(exception,GetMagickModule(),
-                      ResourceLimitError,"MemoryAllocationFailed","'%s'",
+                      ResourceLimitError,"MemoryAllocationFailed","`%s'",
                       image->filename);
                     break;
                   }
@@ -2792,7 +2802,7 @@ MagickExport MagickBooleanType DrawImage(Image *image,const DrawInfo *draw_info,
       if (primitive_info == (PrimitiveInfo *) NULL)
         {
           (void) ThrowMagickException(exception,GetMagickModule(),
-            ResourceLimitError,"MemoryAllocationFailed","'%s'",image->filename);
+            ResourceLimitError,"MemoryAllocationFailed","`%s'",image->filename);
           break;
         }
     }
@@ -2839,7 +2849,7 @@ MagickExport MagickBooleanType DrawImage(Image *image,const DrawInfo *draw_info,
       {
         if (primitive_info[j].coordinates > 107)
           (void) ThrowMagickException(exception,GetMagickModule(),DrawError,
-            "TooManyBezierCoordinates","'%s'",token);
+            "TooManyBezierCoordinates","`%s'",token);
         length=BezierQuantum*primitive_info[j].coordinates;
         break;
       }
@@ -2898,7 +2908,7 @@ MagickExport MagickBooleanType DrawImage(Image *image,const DrawInfo *draw_info,
         if (primitive_info == (PrimitiveInfo *) NULL)
           {
             (void) ThrowMagickException(exception,GetMagickModule(),
-              ResourceLimitError,"MemoryAllocationFailed","'%s'",
+              ResourceLimitError,"MemoryAllocationFailed","`%s'",
               image->filename);
             break;
           }
@@ -3096,9 +3106,10 @@ MagickExport MagickBooleanType DrawImage(Image *image,const DrawInfo *draw_info,
         if ((n != 0) && (graphic_context[n]->clip_mask != (char *) NULL) &&
             (LocaleCompare(graphic_context[n]->clip_mask,
              graphic_context[n-1]->clip_mask) != 0))
-          (void) DrawClipPath(image,graphic_context[n],
+          status&=DrawClipPath(image,graphic_context[n],
             graphic_context[n]->clip_mask,exception);
-        (void) DrawPrimitive(image,graphic_context[n],primitive_info,exception);
+        status&=DrawPrimitive(image,graphic_context[n],primitive_info,
+          exception);
       }
     if (primitive_info->text != (char *) NULL)
       primitive_info->text=(char *) RelinquishMagickMemory(
@@ -3107,6 +3118,8 @@ MagickExport MagickBooleanType DrawImage(Image *image,const DrawInfo *draw_info,
       primitive_extent);
     if (proceed == MagickFalse)
       break;
+    if (status == 0)
+      break;
   }
   if (image->debug != MagickFalse)
     (void) LogMagickEvent(DrawEvent,GetMagickModule(),"end draw-image");
@@ -3123,7 +3136,7 @@ MagickExport MagickBooleanType DrawImage(Image *image,const DrawInfo *draw_info,
   if (status == MagickFalse)
     ThrowBinaryException(DrawError,"NonconformingDrawingPrimitiveDefinition",
       keyword);
-  return(status);
+  return(status != 0 ? MagickTrue : MagickFalse);
 }
 \f
 /*
@@ -3220,26 +3233,21 @@ MagickExport MagickBooleanType DrawGradientImage(Image *image,
   const SegmentInfo
     *gradient_vector;
 
+  double
+    length;
+
   MagickBooleanType
     status;
 
   PixelInfo
     zero;
 
-  double
-    length;
-
   PointInfo
     point;
 
   RectangleInfo
     bounding_box;
 
-#if defined(MAGICKCORE_OPENMP_SUPPORT)
-  size_t
-    height;
-#endif
-
   ssize_t
     y;
 
@@ -3259,13 +3267,10 @@ MagickExport MagickBooleanType DrawGradientImage(Image *image,
   bounding_box=gradient->bounding_box;
   status=MagickTrue;
   GetPixelInfo(image,&zero);
-#if defined(MAGICKCORE_OPENMP_SUPPORT)
-  height=bounding_box.height-bounding_box.y;
-#endif
   image_view=AcquireAuthenticCacheView(image,exception);
 #if defined(MAGICKCORE_OPENMP_SUPPORT)
   #pragma omp parallel for schedule(static,4) shared(status) \
-    magick_threads(image,image,height,1)
+    magick_threads(image,image,1,1)
 #endif
   for (y=bounding_box.y; y < (ssize_t) bounding_box.height; y++)
   {
@@ -3517,7 +3522,7 @@ MagickExport MagickBooleanType DrawPatternPath(Image *image,
   image_info->size=AcquireString(geometry);
   *pattern=AcquireImage(image_info,exception);
   image_info=DestroyImageInfo(image_info);
-  (void) QueryColorCompliance("#00000000",AllCompliance,
+  (void) QueryColorCompliance("#000000ff",AllCompliance,
     &(*pattern)->background_color,exception);
   (void) SetImageBackgroundColor(*pattern,exception);
   if (image->debug != MagickFalse)
@@ -3692,7 +3697,7 @@ static double GetFillAlpha(PolygonInfo *polygon_info,const double mid,
             }
           else
             {
-              alpha=PerceptibleReciprocal(alpha);
+              alpha=1.0/alpha;
               beta=delta.x*(y-q->y)-delta.y*(x-q->x);
               distance=alpha*beta*beta;
             }
@@ -3809,11 +3814,6 @@ static MagickBooleanType DrawPolygonPrimitive(Image *image,
   SegmentInfo
     bounds;
 
-#if defined(MAGICKCORE_OPENMP_SUPPORT)
-  size_t
-    height;
-#endif
-
   ssize_t
     start,
     stop,
@@ -3834,8 +3834,10 @@ static MagickBooleanType DrawPolygonPrimitive(Image *image,
   polygon_info=AcquirePolygonThreadSet(draw_info,primitive_info);
   if (polygon_info == (PolygonInfo **) NULL)
     return(MagickFalse);
+DisableMSCWarning(4127)
   if (0)
     DrawBoundingRectangles(image,draw_info,polygon_info[0],exception);
+RestoreMSCWarning
   if (image->debug != MagickFalse)
     (void) LogMagickEvent(DrawEvent,GetMagickModule(),"    begin draw-polygon");
   fill=(primitive_info->method == FillToBorderMethod) ||
@@ -3868,9 +3870,6 @@ static MagickBooleanType DrawPolygonPrimitive(Image *image,
     image->rows ? (double) image->rows-1 : bounds.y2;
   status=MagickTrue;
   image_view=AcquireAuthenticCacheView(image,exception);
-#if defined(MAGICKCORE_OPENMP_SUPPORT)
-  height=(size_t) (floor(bounds.y2+0.5)-ceil(bounds.y1-0.5));
-#endif
   if (primitive_info->coordinates == 1)
     {
       /*
@@ -3880,7 +3879,7 @@ static MagickBooleanType DrawPolygonPrimitive(Image *image,
       stop=(ssize_t) floor(bounds.y2+0.5);
 #if defined(MAGICKCORE_OPENMP_SUPPORT)
       #pragma omp parallel for schedule(static,4) shared(status) \
-        magick_threads(image,image,height,1)
+        magick_threads(image,image,1,1)
 #endif
       for (y=start; y <= stop; y++)
       {
@@ -3943,7 +3942,7 @@ static MagickBooleanType DrawPolygonPrimitive(Image *image,
   stop=(ssize_t) floor(bounds.y2+0.5);
 #if defined(MAGICKCORE_OPENMP_SUPPORT)
   #pragma omp parallel for schedule(static,4) shared(status) \
-    magick_threads(image,image,height,1)
+    magick_threads(image,image,1,1)
 #endif
   for (y=start; y <= stop; y++)
   {
@@ -4172,7 +4171,7 @@ MagickExport MagickBooleanType DrawPrimitive(Image *image,
   if ((IsGrayColorspace(image->colorspace) != MagickFalse) &&
       ((IsPixelInfoGray(&draw_info->fill) == MagickFalse) ||
        (IsPixelInfoGray(&draw_info->stroke) == MagickFalse)))
-    (void) SetImageColorspace(image,RGBColorspace,exception);
+    (void) SetImageColorspace(image,sRGBColorspace,exception);
   status=MagickTrue;
   x=(ssize_t) ceil(primitive_info->point.x-0.5);
   y=(ssize_t) ceil(primitive_info->point.y-0.5);
@@ -4274,7 +4273,7 @@ MagickExport MagickBooleanType DrawPrimitive(Image *image,
               target.green=(double) draw_info->border_color.green;
               target.blue=(double) draw_info->border_color.blue;
             }
-          (void) FloodfillPaintImage(image,draw_info,&target,x,y,
+          status&=FloodfillPaintImage(image,draw_info,&target,x,y,
             primitive_info->method == FloodfillMethod ? MagickFalse :
             MagickTrue,exception);
           break;
@@ -4397,7 +4396,7 @@ MagickExport MagickBooleanType DrawPrimitive(Image *image,
               target.blue=(double) draw_info->border_color.blue;
             }
           channel_mask=SetImageChannelMask(image,AlphaChannel);
-          (void) FloodfillPaintImage(image,draw_info,&target,x,y,
+          status&=FloodfillPaintImage(image,draw_info,&target,x,y,
             primitive_info->method == FloodfillMethod ? MagickFalse :
             MagickTrue,exception);
           (void) SetImageChannelMask(image,channel_mask);
@@ -4453,7 +4452,7 @@ MagickExport MagickBooleanType DrawPrimitive(Image *image,
       (void) FormatLocaleString(geometry,MaxTextExtent,"%+f%+f",
         primitive_info->point.x,primitive_info->point.y);
       (void) CloneString(&clone_info->geometry,geometry);
-      status=AnnotateImage(image,clone_info,exception);
+      status&=AnnotateImage(image,clone_info,exception);
       clone_info=DestroyDrawInfo(clone_info);
       break;
     }
@@ -4560,7 +4559,7 @@ MagickExport MagickBooleanType DrawPrimitive(Image *image,
           clone_info=CloneDrawInfo((ImageInfo *) NULL,draw_info);
           clone_info->stroke_width=0.0;
           clone_info->stroke.alpha=(Quantum) TransparentAlpha;
-          status=DrawPolygonPrimitive(image,clone_info,primitive_info,
+          status&=DrawPolygonPrimitive(image,clone_info,primitive_info,
             exception);
           clone_info=DestroyDrawInfo(clone_info);
           (void) DrawDashPolygon(draw_info,primitive_info,image,exception);
@@ -4594,13 +4593,13 @@ MagickExport MagickBooleanType DrawPrimitive(Image *image,
           clone_info=CloneDrawInfo((ImageInfo *) NULL,draw_info);
           clone_info->stroke_width=0.0;
           clone_info->stroke.alpha=(Quantum) TransparentAlpha;
-          status=DrawPolygonPrimitive(image,clone_info,primitive_info,
+          status&=DrawPolygonPrimitive(image,clone_info,primitive_info,
             exception);
           clone_info=DestroyDrawInfo(clone_info);
-          status|=DrawStrokePolygon(image,draw_info,primitive_info,exception);
+          status&=DrawStrokePolygon(image,draw_info,primitive_info,exception);
           break;
         }
-      status=DrawPolygonPrimitive(image,draw_info,primitive_info,exception);
+      status&=DrawPolygonPrimitive(image,draw_info,primitive_info,exception);
       break;
     }
   }
@@ -4668,7 +4667,9 @@ static MagickBooleanType DrawStrokePolygon(Image *image,
     *clone_info;
 
   MagickBooleanType
-    closed_path,
+    closed_path;
+
+  MagickStatusType
     status;
 
   PrimitiveInfo
@@ -4698,7 +4699,9 @@ static MagickBooleanType DrawStrokePolygon(Image *image,
   for (p=primitive_info; p->primitive != UndefinedPrimitive; p+=p->coordinates)
   {
     stroke_polygon=TraceStrokePolygon(draw_info,p);
-    status=DrawPolygonPrimitive(image,clone_info,stroke_polygon,exception);
+    status&=DrawPolygonPrimitive(image,clone_info,stroke_polygon,exception);
+    if (status == 0)
+      break;
     stroke_polygon=(PrimitiveInfo *) RelinquishMagickMemory(stroke_polygon);
     q=p+p->coordinates-1;
     closed_path=(q->point.x == p->point.x) && (q->point.y == p->point.y) ?
@@ -4713,7 +4716,7 @@ static MagickBooleanType DrawStrokePolygon(Image *image,
   if (image->debug != MagickFalse)
     (void) LogMagickEvent(DrawEvent,GetMagickModule(),
       "    end draw-stroke-polygon");
-  return(status);
+  return(status != 0 ? MagickTrue : MagickFalse);
 }
 \f
 /*
@@ -4790,7 +4793,7 @@ MagickExport void GetDrawInfo(const ImageInfo *image_info,DrawInfo *draw_info)
   exception=AcquireExceptionInfo();
   (void) QueryColorCompliance("#000F",AllCompliance,&draw_info->fill,
     exception);
-  (void) QueryColorCompliance("#FFF0",AllCompliance,&draw_info->stroke,
+  (void) QueryColorCompliance("#FFFF",AllCompliance,&draw_info->stroke,
     exception);
   draw_info->stroke_width=1.0;
   draw_info->alpha=OpaqueAlpha;
@@ -5284,12 +5287,15 @@ static size_t TracePath(PrimitiveInfo *primitive_info,const char *path)
     z_count;
 
   attribute=0;
+  end.x=0.0;
+  end.y=0.0;
   point.x=0.0;
   point.y=0.0;
   start.x=0.0;
   start.y=0.0;
   number_coordinates=0;
   z_count=0;
+  (void) ResetMagickMemory(points,0,sizeof(*points));
   primitive_type=primitive_info->primitive;
   q=primitive_info;
   for (p=path; *p != '\0'; )