]> granicus.if.org Git - imagemagick/commitdiff
(no commit message)
authorcristy <urban-warrior@git.imagemagick.org>
Sun, 4 Nov 2012 14:33:51 +0000 (14:33 +0000)
committercristy <urban-warrior@git.imagemagick.org>
Sun, 4 Nov 2012 14:33:51 +0000 (14:33 +0000)
MagickCore/threshold.c
MagickCore/threshold.h
MagickWand/mogrify.c
MagickWand/operation.c
PerlMagick/Magick.xs

index 9279da66cba93678183e2674c37cd993f901e1dc..f877aefc8cc1b522f4279fc6ab904b833f6892f1 100644 (file)
@@ -664,7 +664,9 @@ MagickExport MagickBooleanType BlackThresholdImage(Image *image,
 %                                                                             %
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %
-%  ClampImage() restricts the color range from 0 to the quantum depth.
+%  ClampImage() set each pixel whose value is below zero to zero and any the
+%  pixel whose value is above the quantum range to the quantum range (e.g.
+%  65535) otherwise the pixel value remains unchanged.
 %
 %  The format of the ClampImage method is:
 %
@@ -1442,6 +1444,163 @@ MagickExport MagickBooleanType OrderedPosterizeImage(Image *image,
 %                                                                             %
 %                                                                             %
 %                                                                             %
+%     P e r c e p t i b l e I m a g e                                         %
+%                                                                             %
+%                                                                             %
+%                                                                             %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%  PerceptibleImage() set each pixel whose value is less than |epsilon| to 
+%  epsilon or -epsilon (whichever is closer) otherwise the pixel value remains 
+%  unchanged.
+%
+%  The format of the PerceptibleImage method is:
+%
+%      MagickBooleanType PerceptibleImage(Image *image,const double epsilon,
+%        ExceptionInfo *exception)
+%
+%  A description of each parameter follows:
+%
+%    o image: the image.
+%
+%    o epsilon: the epsilon threshold (e.g. 1.0e-9).
+%
+%    o exception: return any errors or warnings in this structure.
+%
+*/
+
+static inline Quantum PerceptibleThreshold(const Quantum quantum,
+  const double epsilon)
+{
+  double
+    sign;
+
+  sign=(double) quantum < 0.0 ? -1.0 : 1.0;
+  if ((sign*quantum) >= epsilon)
+    return(quantum);
+  return((Quantum) (sign*epsilon));
+}
+
+MagickExport MagickBooleanType PerceptibleImage(Image *image,
+  const double epsilon,ExceptionInfo *exception)
+{
+#define PerceptibleImageTag  "Perceptible/Image"
+
+  CacheView
+    *image_view;
+
+  MagickBooleanType
+    status;
+
+  MagickOffsetType
+    progress;
+
+  ssize_t
+    y;
+
+  assert(image != (Image *) NULL);
+  assert(image->signature == MagickSignature);
+  if (image->debug != MagickFalse)
+    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
+  if (image->storage_class == PseudoClass)
+    {
+      register ssize_t
+        i;
+
+      register PixelInfo
+        *restrict q;
+
+      q=image->colormap;
+      for (i=0; i < (ssize_t) image->colors; i++)
+      {
+        q->red=(double) PerceptibleThreshold(ClampToQuantum(q->red),
+          epsilon);
+        q->green=(double) PerceptibleThreshold(ClampToQuantum(q->green),
+          epsilon);
+        q->blue=(double) PerceptibleThreshold(ClampToQuantum(q->blue),
+          epsilon);
+        q->alpha=(double) PerceptibleThreshold(ClampToQuantum(q->alpha),
+          epsilon);
+        q++;
+      }
+      return(SyncImage(image,exception));
+    }
+  /*
+    Perceptible image.
+  */
+  status=MagickTrue;
+  progress=0;
+  image_view=AcquireAuthenticCacheView(image,exception);
+#if defined(MAGICKCORE_OPENMP_SUPPORT)
+  #pragma omp parallel for schedule(static,4) shared(progress,status) \
+    dynamic_number_threads(image,image->columns,image->rows,1)
+#endif
+  for (y=0; y < (ssize_t) image->rows; y++)
+  {
+    register ssize_t
+      x;
+
+    register Quantum
+      *restrict q;
+
+    if (status == MagickFalse)
+      continue;
+    q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception);
+    if (q == (Quantum *) NULL)
+      {
+        status=MagickFalse;
+        continue;
+      }
+    for (x=0; x < (ssize_t) image->columns; x++)
+    {
+      register ssize_t
+        i;
+
+      if (GetPixelMask(image,q) != 0)
+        {
+          q+=GetPixelChannels(image);
+          continue;
+        }
+      for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
+      {
+        PixelChannel
+          channel;
+
+        PixelTrait
+          traits;
+
+        channel=GetPixelChannelChannel(image,i);
+        traits=GetPixelChannelTraits(image,channel);
+        if (traits == UndefinedPixelTrait)
+          continue;
+        q[i]=PerceptibleThreshold(q[i],epsilon);
+      }
+      q+=GetPixelChannels(image);
+    }
+    if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
+      status=MagickFalse;
+    if (image->progress_monitor != (MagickProgressMonitor) NULL)
+      {
+        MagickBooleanType
+          proceed;
+
+#if defined(MAGICKCORE_OPENMP_SUPPORT)
+        #pragma omp critical (MagickCore_PerceptibleImage)
+#endif
+        proceed=SetImageProgress(image,PerceptibleImageTag,progress++,image->rows);
+        if (proceed == MagickFalse)
+          status=MagickFalse;
+      }
+  }
+  image_view=DestroyCacheView(image_view);
+  return(status);
+}
+\f
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%                                                                             %
+%                                                                             %
+%                                                                             %
 %     R a n d o m T h r e s h o l d I m a g e                                 %
 %                                                                             %
 %                                                                             %
index 53a1855fb885fd4d2d135de012979497949a5632..36d2505198936ac1b1444be87338238f53bd8905 100644 (file)
@@ -39,6 +39,7 @@ extern MagickExport MagickBooleanType
   ClampImage(Image *,ExceptionInfo *),
   ListThresholdMaps(FILE *,ExceptionInfo *),
   OrderedPosterizeImage(Image *,const char *,ExceptionInfo *),
+  PerceptibleImage(Image *,const double,ExceptionInfo *),
   RandomThresholdImage(Image *,const char *,ExceptionInfo *),
   WhiteThresholdImage(Image *,const char *,ExceptionInfo *);
 
index 108fd8400104c25d6b6fb9fe6f58fc393513907b..5a1de7c6381bc9741afd9c1ec83224a9de9201b7 100644 (file)
@@ -1056,13 +1056,14 @@ WandExport MagickBooleanType MogrifyImage(ImageInfo *image_info,const int argc,
             mogrify_image=ChopImage(*image,&geometry,exception);
             break;
           }
-        if (LocaleCompare("clamp",option+1) == 0)
+        if (LocaleCompare("perceptible",option+1) == 0)
           {
             /*
-              Clamp image.
+              Perceptible image.
             */
             (void) SyncImageSettings(mogrify_info,*image,exception);
-            (void) ClampImage(*image,exception);
+            (void) PerceptibleImage(*image,StringToDouble(argv[i+1],
+              (char **) NULL),exception);
             break;
           }
         if (LocaleCompare("clip",option+1) == 0)
index 15791bec5926c77843cc156bc274aba69a5dcb37..7a77d96e1f18dc4e67d39bea34db94603be37d1f 100644 (file)
@@ -2842,6 +2842,12 @@ static void CLISimpleOperatorImage(MagickCLI *cli_wand,
                _exception);
           break;
         }
+      if (LocaleCompare("perceptible",option+1) == 0)
+        {
+          (void) PerceptibleImage(_image,StringToDouble(arg1,(char **) NULL),
+            _exception);
+          break;
+        }
       if (LocaleCompare("polaroid",option+1) == 0)
         {
           const char
index 7f293572131924244e58dc1827ae607fd5064fd6..aec0bc116bbab5d3eddc5461bdd1f98568793551 100644 (file)
@@ -537,7 +537,9 @@ static struct
       {"channel", MagickChannelOptions} } },
     { "Statistic", { {"geometry", StringReference},
       {"width", IntegerReference},{"height", IntegerReference},
-      {"channel", MagickChannelOptions}, {"type", MagickStatisticOptions} } }
+      {"channel", MagickChannelOptions}, {"type", MagickStatisticOptions} } },
+    { "Perceptible", { {"epsilon", RealReference},
+      {"channel", MagickChannelOptions} } }
   };
 
 static SplayTreeInfo
@@ -7353,6 +7355,8 @@ Mogrify(ref,...)
     ModeImage          = 268
     Statistic          = 269
     StatisticImage     = 270
+    Perceptible        = 271
+    PerceptibleImage   = 272
     MogrifyRegion      = 666
   PPCODE:
   {
@@ -10910,6 +10914,19 @@ Mogrify(ref,...)
             (void) SetImageChannelMask(image,channel_mask);
           break;
         }
+        case 135:  /* Perceptible */
+        {
+          double
+            epsilon;
+
+          epsilon=MagickEpsilon;
+          if (attribute_flag[0] != 0)
+            epsilon=argument_list[0].real_reference;
+          if (attribute_flag[1] != 0)
+            channel=(ChannelType) argument_list[1].integer_reference;
+          (void) PerceptibleImageChannel(image,channel,epsilon,exception);
+          break;
+        }
       }
       if (next != (Image *) NULL)
         (void) CatchImageException(next);