]> granicus.if.org Git - imagemagick/commitdiff
(no commit message)
authorcristy <urban-warrior@git.imagemagick.org>
Fri, 25 Sep 2009 16:38:06 +0000 (16:38 +0000)
committercristy <urban-warrior@git.imagemagick.org>
Fri, 25 Sep 2009 16:38:06 +0000 (16:38 +0000)
PerlMagick/Magick.xs
magick/threshold.c
magick/threshold.h
wand/convert.c
wand/magick-image.c
wand/magick-image.h
wand/mogrify.c

index 67bfaa67ea748914c7f06f63d3c087380a37ac06..5761f4664f746ba56e48771d0ddba7a9ee10d2e7 100644 (file)
@@ -519,6 +519,7 @@ static struct
     { "LevelColors", { {"invert", MagickBooleanOptions},
       {"black-point", RealReference}, {"white-point", RealReference},
       {"channel", MagickChannelOptions}, {"invert", MagickBooleanOptions} } },
+    { "Clamp", { {"channel", MagickChannelOptions} } },
   };
 
 static SplayTreeInfo
@@ -6764,6 +6765,8 @@ Mogrify(ref,...)
     AutoLevelImage     = 256
     LevelColors        = 257
     LevelColorsImage   = 258
+    Clamp              = 259
+    ClampImage         = 260
     MogrifyRegion      = 666
   PPCODE:
   {
@@ -9960,8 +9963,16 @@ Mogrify(ref,...)
                &white_point,exception);
           if (attribute_flag[3] != 0)
             channel=(ChannelType) argument_list[3].long_reference;
-          (void) LevelColorsImageChannel(image,channel,&black_point,&white_point,
-            argument_list[0].long_reference != 0 ? MagickTrue : MagickFalse);
+          (void) LevelColorsImageChannel(image,channel,&black_point,
+            &white_point,argument_list[0].long_reference != 0 ? MagickTrue :
+            MagickFalse);
+          break;
+        }
+        case 130:  /* Clamp */
+        {
+          if (attribute_flag[0] != 0)
+            channel=(ChannelType) argument_list[0].long_reference;
+          (void) ClampImageChannel(image,channel);
           break;
         }
       }
index 6fb1521cf9ca544163db4142c55bfe5cdc151b59..089132b608eca97cc8192f81bb025e78a4918931 100644 (file)
@@ -654,6 +654,161 @@ MagickExport MagickBooleanType BlackThresholdImageChannel(Image *image,
 %                                                                             %
 %                                                                             %
 %                                                                             %
+%     C l a m p I m a g e                                                     %
+%                                                                             %
+%                                                                             %
+%                                                                             %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%  ClampImage() restricts the color range from 0 to QuantumDepth.
+%
+%  The format of the ClampImageChannel method is:
+%
+%      MagickBooleanType ClampImage(Image *image)
+%      MagickBooleanType ClampImageChannel(Image *image,
+%        const ChannelType channel)
+%
+%  A description of each parameter follows:
+%
+%    o image: the image.
+%
+%    o channel: the channel type.
+%
+*/
+
+static inline Quantum ClampToQuantum(const Quantum quantum)
+{
+#if defined(MAGICKCORE_HDRI_SUPPORT)
+  if (quantum <= 0)
+    return(0);
+  if (quantum >= QuantumRange)
+    return(QuantumRange);
+  return(quantum);
+#else
+  return(quantum);
+#endif
+}
+
+MagickExport MagickBooleanType ClampImage(Image *image)
+{
+  MagickBooleanType
+    status;
+
+  status=ClampImageChannel(image,DefaultChannels);
+  return(status);
+}
+
+MagickExport MagickBooleanType ClampImageChannel(Image *image,
+  const ChannelType channel)
+{
+#define ClampImageTag  "Clamp/Image"
+
+  ExceptionInfo
+    *exception;
+
+  long
+    progress,
+    y;
+
+  MagickBooleanType
+    status;
+
+  CacheView
+    *image_view;
+
+  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 long
+        i;
+
+      register PixelPacket
+        *__restrict q;
+
+      q=image->colormap;
+      for (i=0; i < (long) image->colors; i++)
+      {
+        q->red=ClampToQuantum(q->red);
+        q->green=ClampToQuantum(q->green);
+        q->blue=ClampToQuantum(q->blue);
+        q->opacity=ClampToQuantum(q->opacity);
+        q++;
+      }
+      return(SyncImage(image));
+    }
+  /*
+    Clamp threshold image.
+  */
+  status=MagickTrue;
+  progress=0;
+  exception=(&image->exception);
+  image_view=AcquireCacheView(image);
+#if defined(_OPENMP) && (_OPENMP >= 200203)
+  #pragma omp parallel for schedule(static,1) shared(progress,status)
+#endif
+  for (y=0; y < (long) image->rows; y++)
+  {
+    register IndexPacket
+      *__restrict indexes;
+
+    register long
+      x;
+
+    register PixelPacket
+      *__restrict q;
+
+    if (status == MagickFalse)
+      continue;
+    q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception);
+    if (q == (PixelPacket *) NULL)
+      {
+        status=MagickFalse;
+        continue;
+      }
+    indexes=GetCacheViewAuthenticIndexQueue(image_view);
+    for (x=0; x < (long) image->columns; x++)
+    {
+      if ((channel & RedChannel) != 0)
+        q->red=ClampToQuantum(q->red);
+      if ((channel & GreenChannel) != 0)
+        q->green=ClampToQuantum(q->green);
+      if ((channel & BlueChannel) != 0)
+        q->blue=ClampToQuantum(q->blue);
+      if ((channel & OpacityChannel) != 0)
+        q->opacity=ClampToQuantum(q->opacity);
+      if (((channel & IndexChannel) != 0) &&
+          (image->colorspace == CMYKColorspace))
+        indexes[x]=(IndexPacket) ClampToQuantum(indexes[x]);
+      q++;
+    }
+    if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
+      status=MagickFalse;
+    if (image->progress_monitor != (MagickProgressMonitor) NULL)
+      {
+        MagickBooleanType
+          proceed;
+
+#if defined(_OPENMP) && (_OPENMP >= 200203)
+  #pragma omp critical (MagickCore_ClampImageChannel)
+#endif
+        proceed=SetImageProgress(image,ClampImageTag,progress++,
+          image->rows);
+        if (proceed == MagickFalse)
+          status=MagickFalse;
+      }
+  }
+  image_view=DestroyCacheView(image_view);
+  return(status);
+}
+\f
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%                                                                             %
+%                                                                             %
+%                                                                             %
 %  D e s t r o y T h r e s h o l d M a p                                      %
 %                                                                             %
 %                                                                             %
index 76baa6bf2b664150b312884ff2dbb8ebd8939f9c..6597c529cc61497ea4dd3cb7494eb521a7b0485e 100644 (file)
@@ -39,6 +39,8 @@ extern MagickExport MagickBooleanType
   BlackThresholdImage(Image *,const char *),
   BlackThresholdImageChannel(Image *,const ChannelType,const char *,
     ExceptionInfo *),
+  ClampImage(Image *),
+  ClampImageChannel(Image *,const ChannelType),
   ListThresholdMaps(FILE *,ExceptionInfo *),
   OrderedDitherImage(Image *),  /* deprecated */
   OrderedDitherImageChannel(Image *,const ChannelType,ExceptionInfo *),
index aad7de920411c055965de247a61bdb4e14190870..8b2765162685f40664bda98e38b35d8a6a7f7b92 100644 (file)
@@ -164,6 +164,7 @@ static MagickBooleanType ConvertUsage(void)
       "-cdl filename        color correct with a color decision list",
       "-charcoal radius     simulate a charcoal drawing",
       "-chop geometry       remove pixels from the image interior",
+      "-clamp               restrict pixel range from 0 to QuantumDepth",
       "-clip                clip along the first path from the 8BIM profile",
       "-clip-mask filename  associate a clip mask with the image",
       "-clip-path id        clip along a named path from the 8BIM profile",
@@ -867,6 +868,8 @@ WandExport MagickBooleanType ConvertImageCommand(ImageInfo *image_info,
               ThrowConvertInvalidArgumentException(option,argv[i]);
             break;
           }
+        if (LocaleCompare("clamp",option+1) == 0)
+          break;
         if (LocaleCompare("clip",option+1) == 0)
           break;
         if (LocaleCompare("clip-mask",option+1) == 0)
index 0d9b2cd95a566c498117cb35e763fe4d81bf6c99..70a07ecfd574726fc18ba0fb5939b37ec6f75e84 100644 (file)
@@ -1220,6 +1220,60 @@ WandExport MagickBooleanType MagickChopImage(MagickWand *wand,
 %                                                                             %
 %                                                                             %
 %                                                                             %
+%   M a g i c k C l a m p I m a g e                                           %
+%                                                                             %
+%                                                                             %
+%                                                                             %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%  MagickClampImage() restricts the color range from 0 to QuantumDepth.
+%
+%  The format of the MagickClampImage method is:
+%
+%      MagickBooleanType MagickClampImage(MagickWand *wand)
+%      MagickBooleanType MagickClampImageChannel(MagickWand *wand,
+%        const ChannelType channel)
+%
+%  A description of each parameter follows:
+%
+%    o wand: the magick wand.
+%
+%    o channel: the channel.
+%
+*/
+
+WandExport MagickBooleanType MagickClampImage(MagickWand *wand)
+{
+  MagickBooleanType
+    status;
+
+  status=MagickClampImageChannel(wand,DefaultChannels);
+  return(status);
+}
+
+WandExport MagickBooleanType MagickClampImageChannel(MagickWand *wand,
+  const ChannelType channel)
+{
+  MagickBooleanType
+    status;
+
+  assert(wand != (MagickWand *) NULL);
+  assert(wand->signature == WandSignature);
+  if (wand->debug != MagickFalse)
+    (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
+  if (wand->images == (Image *) NULL)
+    ThrowWandException(WandError,"ContainsNoImages",wand->name);
+  status=ClampImageChannel(wand->images,channel);
+  if (status == MagickFalse)
+    InheritException(wand->exception,&wand->images->exception);
+  return(status);
+}
+\f
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%                                                                             %
+%                                                                             %
+%                                                                             %
 %   M a g i c k C l i p I m a g e                                             %
 %                                                                             %
 %                                                                             %
index 58cfe1704d8d6857e25e64e4792f9873e2939d61..f797f1608f0415fc50c33f196d529ae546d55fc4 100644 (file)
@@ -99,6 +99,8 @@ extern WandExport MagickBooleanType
   MagickCharcoalImage(MagickWand *,const double,const double),
   MagickChopImage(MagickWand *,const unsigned long,const unsigned long,
     const long,const long),
+  MagickClampImage(MagickWand *),
+  MagickClampImageChannel(MagickWand *,const ChannelType),
   MagickClipImage(MagickWand *),
   MagickClipImagePath(MagickWand *,const char *,const MagickBooleanType),
   MagickClutImage(MagickWand *,const MagickWand *),
index e6464e5d3fee6077e5cea20b09a586a2875819cc..d73e62ebaf9ad5c2bb8fe036ae49d7bfe397c2ba 100644 (file)
@@ -854,6 +854,16 @@ WandExport MagickBooleanType MogrifyImage(ImageInfo *image_info,const int argc,
             *image=chop_image;
             break;
           }
+        if (LocaleCompare("clamp",option+1) == 0)
+          {
+            /*
+              Clamp image.
+            */
+            (void) SyncImageSettings(image_info,*image);
+            (void) ClampImageChannel(*image,channel);
+            InheritException(exception,&(*image)->exception);
+            break;
+          }
         if (LocaleCompare("clip",option+1) == 0)
           {
             (void) SyncImageSettings(image_info,*image);
@@ -3452,6 +3462,7 @@ static MagickBooleanType MogrifyUsage(void)
       "-cdl filename        color correct with a color decision list",
       "-charcoal radius     simulate a charcoal drawing",
       "-chop geometry       remove pixels from the image interior",
+      "-clamp               restrict pixel range from 0 to QuantumDepth",
       "-clip                clip along the first path from the 8BIM profile",
       "-clip-mask filename  associate a clip mask with the image",
       "-clip-path id        clip along a named path from the 8BIM profile",
@@ -4190,6 +4201,10 @@ WandExport MagickBooleanType MogrifyImageCommand(ImageInfo *image_info,
               ThrowMogrifyInvalidArgumentException(option,argv[i]);
             break;
           }
+        if (LocaleCompare("clamp",option+1) == 0)
+          break;
+        if (LocaleCompare("clip",option+1) == 0)
+          break;
         if (LocaleCompare("clip-mask",option+1) == 0)
           {
             if (*option == '+')