From: cristy Date: Mon, 25 Mar 2013 11:30:44 +0000 (+0000) Subject: (no commit message) X-Git-Tag: 7.0.1-0~4012 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=3afd4014cd833bc3c170cb54e37c925ceacd17de;p=imagemagick --- diff --git a/Magick++/demo/demo.cpp b/Magick++/demo/demo.cpp index fe63d7538..1535b6769 100644 --- a/Magick++/demo/demo.cpp +++ b/Magick++/demo/demo.cpp @@ -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; diff --git a/Magick++/lib/Image.cpp b/Magick++/lib/Image.cpp index db173d7e0..b979e6845 100644 --- a/Magick++/lib/Image.cpp +++ b/Magick++/lib/Image.cpp @@ -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 ); diff --git a/Magick++/lib/Magick++/Image.h b/Magick++/lib/Magick++/Image.h index 4b232a081..3b15175eb 100644 --- a/Magick++/lib/Magick++/Image.h +++ b/Magick++/lib/Magick++/Image.h @@ -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, diff --git a/Magick++/lib/Magick++/STL.h b/Magick++/lib/Magick++/STL.h index bc629a8ff..d4c30a183 100644 --- a/Magick++/lib/Magick++/STL.h +++ b/Magick++/lib/Magick++/STL.h @@ -389,12 +389,13 @@ namespace Magick class MagickPPExport edgeImage : public std::unary_function { 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) diff --git a/MagickCore/effect.c b/MagickCore/effect.c index 1d4396f5b..ce837f551 100644 --- a/MagickCore/effect.c +++ b/MagickCore/effect.c @@ -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); } diff --git a/MagickCore/effect.h b/MagickCore/effect.h index 9245cf2e7..fb771e7cc 100644 --- a/MagickCore/effect.h +++ b/MagickCore/effect.h @@ -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) } diff --git a/MagickWand/magick-image.c b/MagickWand/magick-image.c index 18343f028..990ff7246 100644 --- a/MagickWand/magick-image.c +++ b/MagickWand/magick-image.c @@ -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); diff --git a/MagickWand/magick-image.h b/MagickWand/magick-image.h index bdc3d4eae..319df504b 100644 --- a/MagickWand/magick-image.h +++ b/MagickWand/magick-image.h @@ -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, diff --git a/MagickWand/mogrify.c b/MagickWand/mogrify.c index 6d3894cbf..f473ef783 100644 --- a/MagickWand/mogrify.c +++ b/MagickWand/mogrify.c @@ -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; diff --git a/MagickWand/operation.c b/MagickWand/operation.c index 87698e192..6d4f8bddd 100644 --- a/MagickWand/operation.c +++ b/MagickWand/operation.c @@ -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); diff --git a/PerlMagick/quantum/quantum.xs.in b/PerlMagick/quantum/quantum.xs.in index 0eec13529..e5a82dd1c 100644 --- a/PerlMagick/quantum/quantum.xs.in +++ b/PerlMagick/quantum/quantum.xs.in @@ -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;