]> granicus.if.org Git - imagemagick/commitdiff
(no commit message)
authorcristy <urban-warrior@git.imagemagick.org>
Mon, 25 Mar 2013 11:30:44 +0000 (11:30 +0000)
committercristy <urban-warrior@git.imagemagick.org>
Mon, 25 Mar 2013 11:30:44 +0000 (11:30 +0000)
Magick++/demo/demo.cpp
Magick++/lib/Image.cpp
Magick++/lib/Magick++/Image.h
Magick++/lib/Magick++/STL.h
MagickCore/effect.c
MagickCore/effect.h
MagickWand/magick-image.c
MagickWand/magick-image.h
MagickWand/mogrify.c
MagickWand/operation.c
PerlMagick/quantum/quantum.xs.in

index fe63d7538020d52c95b0260f4532517b24833cdd..1535b676993e2b1e6a737bf1c9e8ca3a32c8236c 100644 (file)
@@ -440,8 +440,8 @@ int main( int /*argc*/, char ** argv)
       cout << "  unsharp mask ..." << endl;
       example = model;
       example.label( "Unsharp Mask" );
-      //           radius_, sigma_, gain_
-      example.unsharpmask( 0.0, 1.0, 1.0);
+      //           radius_, sigma_, amount_, threshold_
+      example.unsharpmask( 0.0, 1.0, 1.0, 0.05);
       images.push_back( example );
     
       cout << "  wave ..." << endl;
index db173d7e0811c993ca0e1947c198ad6ce6d07be3..b979e68453c8d9bbd6c69953c51346423d4c122e 100644 (file)
@@ -2282,7 +2282,8 @@ void Magick::Image::trim ( void )
 //   the threshold in pixels needed to apply the diffence amount.
 void Magick::Image::unsharpmask ( const double radius_,
                                   const double sigma_,
-                                  const double gain_ )
+                                  const double amount_,
+                                  const double threshold_ )
 {
   ExceptionInfo exceptionInfo;
   GetExceptionInfo( &exceptionInfo );
@@ -2290,7 +2291,8 @@ void Magick::Image::unsharpmask ( const double radius_,
     UnsharpMaskImage( image(),
                       radius_,
                       sigma_,
-                      gain_,
+                      amount_,
+                      threshold_,
                       &exceptionInfo );
   replaceImage( newImage );
   throwException( exceptionInfo );
@@ -2300,7 +2302,8 @@ void Magick::Image::unsharpmask ( const double radius_,
 void Magick::Image::unsharpmaskChannel ( const ChannelType channel_,
                                          const double radius_,
                                          const double sigma_,
-                                         const double gain_ )
+                                         const double amount_,
+                                         const double threshold_ )
 {
   ExceptionInfo exceptionInfo;
   GetExceptionInfo( &exceptionInfo );
@@ -2309,7 +2312,8 @@ void Magick::Image::unsharpmaskChannel ( const ChannelType channel_,
     UnsharpMaskImage( image(),
                              radius_,
                              sigma_,
-                             gain_,
+                             amount_,
+                             threshold_,
                              &exceptionInfo );
   (void) SetPixelChannelMask( image(), channel_mask );
   replaceImage( newImage );
index 4b232a081634602940f8b60b03cf7b3832e7a7b6..3b15175eb2a99c0f9872866d5cb942eb404e0c04 100644 (file)
@@ -259,7 +259,7 @@ namespace Magick
     void            crop ( const Geometry &geometry_ );
     
     // Cycle image colormap
-    void            cycleColormap ( const ::ssize_t gain_ );
+    void            cycleColormap ( const ::ssize_t amount_ );
     
     // Despeckle image (reduce speckle noise)
     void            despeckle ( void );
@@ -640,7 +640,7 @@ namespace Magick
     void            splice ( const Geometry &geometry_ );
 
     // Spread pixels randomly within image by specified ammount
-    void            spread ( const size_t gain_ = 3 );
+    void            spread ( const size_t amount_ = 3 );
     
     // Sparse color image, given a set of coordinates, interpolates the colors
     // found at those coordinates, across the whole image, using various
@@ -700,18 +700,20 @@ namespace Magick
     //    center pixel.
     //  sigma_
     //    the standard deviation of the Gaussian, in pixels.
-    //  gain_
+    //  amount_
     //    the percentage of the difference between the original and
     //    the blur image that is added back into the original.
     // threshold_
     //   the threshold in pixels needed to apply the diffence amount.
     void            unsharpmask ( const double radius_,
                                   const double sigma_,
-                                  const double gain_ );
+                                  const double amount_,
+                                  const double threshold_ );
     void            unsharpmaskChannel ( const ChannelType channel_,
                                          const double radius_,
                                          const double sigma_,
-                                         const double gain_ );
+                                         const double amount_,
+                                         const double threshold_ );
 
     // Map image pixels to a sine wave
     void            wave ( const double amplitude_ = 25.0,
index bc629a8ffd31912e162bdcd54f919bc3761d07e2..d4c30a1833d308cbae26b5226f3dc7dcf315df8a 100644 (file)
@@ -389,12 +389,13 @@ namespace Magick
   class MagickPPExport edgeImage : public std::unary_function<Image&,void>
   {
   public:
-    edgeImage( const double radius_ = 0.0 );
+    edgeImage( const double radius_ = 0.0, const double sigma_ = 0.5  );
 
     void operator()( Image &image_ ) const;
 
   private:
     double _radius;
+    double _sigma;
   };
 
   // Emboss image (hilight edges with 3D effect)
index 1d4396f5bed3f30bcc8e583708b9370ca4dcc710..ce837f55142bc1f9adb85b56d70f437429b2afa9 100644 (file)
@@ -3325,7 +3325,8 @@ MagickExport Image *SpreadImage(const Image *image,const double radius,
 %  The format of the UnsharpMaskImage method is:
 %
 %    Image *UnsharpMaskImage(const Image *image,const double radius,
-%      const double sigma,const double gain,ExceptionInfo *exception)
+%      const double sigma,const double amount,const double threshold,
+%      ExceptionInfo *exception)
 %
 %  A description of each parameter follows:
 %
@@ -3339,37 +3340,135 @@ MagickExport Image *SpreadImage(const Image *image,const double radius,
 %    o gain: the percentage of the difference between the original and the
 %      blur image that is added back into the original.
 %
+%    o threshold: the threshold in pixels needed to apply the diffence gain.
+%
 %    o exception: return any errors or warnings in this structure.
 %
 */
 MagickExport Image *UnsharpMaskImage(const Image *image,const double radius,
-  const double sigma,const double gain,ExceptionInfo *exception)
+  const double sigma,const double gain,const double threshold,
+  ExceptionInfo *exception)
 {
-  char
-    geometry[MaxTextExtent];
+#define SharpenImageTag  "Sharpen/Image"
 
-  KernelInfo
-    *kernel_info;
+  CacheView
+    *image_view,
+    *unsharp_view;
 
   Image
     *unsharp_image;
 
+  MagickBooleanType
+    status;
+
+  MagickOffsetType
+    progress;
+
+  double
+    quantum_threshold;
+
+  ssize_t
+    y;
+
   assert(image != (const Image *) NULL);
   assert(image->signature == MagickSignature);
   if (image->debug != MagickFalse)
     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
   assert(exception != (ExceptionInfo *) NULL);
-  assert(exception->signature == MagickSignature);
-  (void) FormatLocaleString(geometry,MaxTextExtent,"Blur:%.20gx%.20g>",
-    radius,sigma);
-  kernel_info=AcquireKernelInfo(geometry);
-  if (kernel_info == (KernelInfo *) NULL)
-    ThrowImageException(ResourceLimitError,"MemoryAllocationFailed");
-  (void) FormatLocaleString(geometry,MaxTextExtent,"%.20g,%.20g%%",
-    -100.0+gain*100.0,200.0-gain*100.0);
-  ScaleGeometryKernelInfo(kernel_info,geometry);
-  unsharp_image=MorphologyImage(image,ConvolveMorphology,1,kernel_info,
-    exception);
-  kernel_info=DestroyKernelInfo(kernel_info);
+  unsharp_image=BlurImage(image,radius,sigma,exception);
+  if (unsharp_image == (Image *) NULL)
+    return((Image *) NULL);
+  quantum_threshold=(double) QuantumRange*threshold;
+  /*
+    Unsharp-mask image.
+  */
+  status=MagickTrue;
+  progress=0;
+  image_view=AcquireVirtualCacheView(image,exception);
+  unsharp_view=AcquireAuthenticCacheView(unsharp_image,exception);
+#if defined(MAGICKCORE_OPENMP_SUPPORT)
+  #pragma omp parallel for schedule(static,4) shared(progress,status) \
+    magick_threads(image,unsharp_image,image->rows,1)
+#endif
+  for (y=0; y < (ssize_t) image->rows; y++)
+  {
+    register const Quantum
+      *restrict p;
+
+    register Quantum
+      *restrict q;
+
+    register ssize_t
+      x;
+
+    if (status == MagickFalse)
+      continue;
+    p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
+    q=QueueCacheViewAuthenticPixels(unsharp_view,0,y,unsharp_image->columns,1,
+      exception);
+    if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
+      {
+        status=MagickFalse;
+        continue;
+      }
+    for (x=0; x < (ssize_t) image->columns; x++)
+    {
+      register ssize_t
+        i;
+
+      for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
+      {
+        double
+          pixel;
+
+        PixelChannel
+          channel;
+
+        PixelTrait
+          traits,
+          unsharp_traits;
+
+        channel=GetPixelChannelChannel(image,i);
+        traits=GetPixelChannelTraits(image,channel);
+        unsharp_traits=GetPixelChannelTraits(unsharp_image,channel);
+        if ((traits == UndefinedPixelTrait) ||
+            (unsharp_traits == UndefinedPixelTrait))
+          continue;
+        if (((unsharp_traits & CopyPixelTrait) != 0) ||
+            (GetPixelMask(image,p) != 0))
+          {
+            SetPixelChannel(unsharp_image,channel,p[i],q);
+            continue;
+          }
+        pixel=p[i]-(double) GetPixelChannel(unsharp_image,channel,q);
+        if (fabs(2.0*pixel) < quantum_threshold)
+          pixel=(double) p[i];
+        else
+          pixel=(double) p[i]+gain*pixel;
+        SetPixelChannel(unsharp_image,channel,ClampToQuantum(pixel),q);
+      }
+      p+=GetPixelChannels(image);
+      q+=GetPixelChannels(unsharp_image);
+    }
+    if (SyncCacheViewAuthenticPixels(unsharp_view,exception) == MagickFalse)
+      status=MagickFalse;
+    if (image->progress_monitor != (MagickProgressMonitor) NULL)
+      {
+        MagickBooleanType
+          proceed;
+
+#if defined(MAGICKCORE_OPENMP_SUPPORT)
+        #pragma omp critical (MagickCore_UnsharpMaskImage)
+#endif
+        proceed=SetImageProgress(image,SharpenImageTag,progress++,image->rows);
+        if (proceed == MagickFalse)
+          status=MagickFalse;
+      }
+  }
+  unsharp_image->type=image->type;
+  unsharp_view=DestroyCacheView(unsharp_view);
+  image_view=DestroyCacheView(image_view);
+  if (status == MagickFalse)
+    unsharp_image=DestroyImage(unsharp_image);
   return(unsharp_image);
 }
index 9245cf2e74b5c4ec9f61d7542d8c469693f3d351..fb771e7cc30057f5714ed19ce9fb2fae073a2968 100644 (file)
@@ -80,7 +80,7 @@ extern MagickExport Image
   *SpreadImage(const Image *,const double,const PixelInterpolateMethod,
     ExceptionInfo *),
   *UnsharpMaskImage(const Image *,const double,const double,const double,
-    ExceptionInfo *);
+    const double,ExceptionInfo *);
 
 #if defined(__cplusplus) || defined(c_plusplus)
 }
index 18343f028f0ef37d1d2111352534735df87e89f4..990ff72461d86975e76b632c069af08eb621f622 100644 (file)
@@ -11925,7 +11925,8 @@ WandExport MagickBooleanType MagickUniqueImageColors(MagickWand *wand)
 %  The format of the MagickUnsharpMaskImage method is:
 %
 %      MagickBooleanType MagickUnsharpMaskImage(MagickWand *wand,
-%        const double radius,const double sigma,const double gain)
+%        const double radius,const double sigma,const double gain,
+%        const double threshold)
 %
 %  A description of each parameter follows:
 %
@@ -11939,9 +11940,12 @@ WandExport MagickBooleanType MagickUniqueImageColors(MagickWand *wand)
 %    o gain: the percentage of the difference between the original and the
 %      blur image that is added back into the original.
 %
+%    o threshold: the threshold in pixels needed to apply the diffence gain.
+%
 */
 WandExport MagickBooleanType MagickUnsharpMaskImage(MagickWand *wand,
-  const double radius,const double sigma,const double gain)
+  const double radius,const double sigma,const double gain,
+  const double threshold)
 {
   Image
     *unsharp_image;
@@ -11952,7 +11956,7 @@ WandExport MagickBooleanType MagickUnsharpMaskImage(MagickWand *wand,
     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   if (wand->images == (Image *) NULL)
     ThrowWandException(WandError,"ContainsNoImages",wand->name);
-  unsharp_image=UnsharpMaskImage(wand->images,radius,sigma,gain,
+  unsharp_image=UnsharpMaskImage(wand->images,radius,sigma,gain,threshold,
     wand->exception);
   if (unsharp_image == (Image *) NULL)
     return(MagickFalse);
index bdc3d4eae848349139f75edf8388f34bd1521076..319df504bdd4b80efccf1f21784f39f13cc95ab1 100644 (file)
@@ -304,7 +304,8 @@ extern WandExport MagickBooleanType
   MagickThumbnailImage(MagickWand *,const size_t,const size_t),
   MagickTrimImage(MagickWand *,const double),
   MagickUniqueImageColors(MagickWand *),
-  MagickUnsharpMaskImage(MagickWand *,const double,const double,const double),
+  MagickUnsharpMaskImage(MagickWand *,const double,const double,const double,
+    const double),
   MagickVignetteImage(MagickWand *,const double,const double,const ssize_t,
     const ssize_t),
   MagickWaveImage(MagickWand *,const double,const double,
index 6d3894cbf50ce48d5ce3858fc5f916eb0cb94c3e..f473ef783e14454561c6ac569d4da11a74b7edcd 100644 (file)
@@ -3046,7 +3046,8 @@ WandExport MagickBooleanType MogrifyImage(ImageInfo *image_info,const int argc,
             if ((flags & PsiValue) == 0)
               geometry_info.psi=0.05;
             mogrify_image=UnsharpMaskImage(*image,geometry_info.rho,
-              geometry_info.sigma,geometry_info.xi,exception);
+              geometry_info.sigma,geometry_info.xi,geometry_info.psi,
+              exception);
             break;
           }
         break;
index 87698e192d4c5f9b84f3a85f643edb6cc7605a34..6d4f8bddde606cc4582f878885a61c1b0f720c11 100644 (file)
@@ -3336,7 +3336,7 @@ static MagickBooleanType CLISimpleOperatorImage(MagickCLI *cli_wand,
           if ((flags & PsiValue) == 0)
             geometry_info.psi=0.05;
           new_image=UnsharpMaskImage(_image,geometry_info.rho,
-            geometry_info.sigma,geometry_info.xi,_exception);
+            geometry_info.sigma,geometry_info.xi,geometry_info.psi,_exception);
           break;
         }
       CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
index 0eec1352991ea6ba46fdf4f11d08ce53899250e6..e5a82dd1c953bba6a96f7feccc208ef81ab8183b 100644 (file)
@@ -390,7 +390,8 @@ static struct
       { "black-point-compensation", MagickBooleanOptions} } },
     { "UnsharpMask", { {"geometry", StringReference},
       {"radius", RealReference}, {"sigma", RealReference},
-      {"gain", RealReference}, {"channel", MagickChannelOptions} } },
+      {"gain", RealReference}, {"threshold", RealReference},
+      {"channel", MagickChannelOptions} } },
     { "MotionBlur", { {"geometry", StringReference},
       {"radius", RealReference}, {"sigma", RealReference},
       {"angle", RealReference}, {"channel", MagickChannelOptions} } },
@@ -9487,10 +9488,12 @@ Mogrify(ref,...)
           if (attribute_flag[3] != 0)
             geometry_info.xi=argument_list[3].real_reference;
           if (attribute_flag[4] != 0)
-            channel=(ChannelType) argument_list[4].integer_reference;
+            geometry_info.psi=argument_list[4].real_reference;
+          if (attribute_flag[5] != 0)
+            channel=(ChannelType) argument_list[5].integer_reference;
           channel_mask=SetImageChannelMask(image,channel);
           image=UnsharpMaskImage(image,geometry_info.rho,geometry_info.sigma,
-            geometry_info.xi,exception);
+            geometry_info.xi,geometry_info.psi,exception);
           if (image != (Image *) NULL)
             (void) SetImageChannelMask(image,channel_mask);
           break;