From: cristy Date: Sun, 4 Nov 2012 14:33:51 +0000 (+0000) Subject: (no commit message) X-Git-Tag: 7.0.1-0~4758 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=7884a9380b6826befb2773117db32d3877b40ac6;p=imagemagick --- diff --git a/MagickCore/threshold.c b/MagickCore/threshold.c index 9279da66c..f877aefc8 100644 --- a/MagickCore/threshold.c +++ b/MagickCore/threshold.c @@ -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); +} + +/* +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % +% % +% % % R a n d o m T h r e s h o l d I m a g e % % % % % diff --git a/MagickCore/threshold.h b/MagickCore/threshold.h index 53a1855fb..36d250519 100644 --- a/MagickCore/threshold.h +++ b/MagickCore/threshold.h @@ -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 *); diff --git a/MagickWand/mogrify.c b/MagickWand/mogrify.c index 108fd8400..5a1de7c63 100644 --- a/MagickWand/mogrify.c +++ b/MagickWand/mogrify.c @@ -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) diff --git a/MagickWand/operation.c b/MagickWand/operation.c index 15791bec5..7a77d96e1 100644 --- a/MagickWand/operation.c +++ b/MagickWand/operation.c @@ -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 diff --git a/PerlMagick/Magick.xs b/PerlMagick/Magick.xs index 7f2935721..aec0bc116 100644 --- a/PerlMagick/Magick.xs +++ b/PerlMagick/Magick.xs @@ -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);