diff options
Diffstat (limited to 'MagickCore/segment.c')
-rw-r--r-- | MagickCore/segment.c | 226 |
1 files changed, 104 insertions, 122 deletions
diff --git a/MagickCore/segment.c b/MagickCore/segment.c index ba10779d1..25e06954c 100644 --- a/MagickCore/segment.c +++ b/MagickCore/segment.c @@ -17,7 +17,7 @@ % April 1993 % % % % % -% Copyright 1999-2020 ImageMagick Studio LLC, a non-profit organization % +% Copyright 1999-2021 ImageMagick Studio LLC, a non-profit organization % % dedicated to making software imaging solutions freely available. % % % % You may not use this file except in compliance with the License. You may % @@ -221,8 +221,7 @@ static void % The format of the Classify method is: % % MagickBooleanType Classify(Image *image,short **extrema, -% const double cluster_threshold, -% const double weighting_exponent, +% const double cluster_threshold,const double weighting_exponent, % const MagickBooleanType verbose,ExceptionInfo *exception) % % A description of each parameter follows. @@ -246,9 +245,8 @@ static void % */ static MagickBooleanType Classify(Image *image,short **extrema, - const double cluster_threshold, - const double weighting_exponent,const MagickBooleanType verbose, - ExceptionInfo *exception) + const double cluster_threshold,const double weighting_exponent, + const MagickBooleanType verbose,ExceptionInfo *exception) { #define SegmentImageTag "Segment/Image" #define ThrowClassifyException(severity,tag,label) \ @@ -276,6 +274,9 @@ static MagickBooleanType Classify(Image *image,short **extrema, *last_cluster, *next_cluster; + double + *free_squares; + ExtentPacket blue, green, @@ -284,16 +285,13 @@ static MagickBooleanType Classify(Image *image,short **extrema, MagickOffsetType progress; - double - *free_squares; - MagickStatusType status; - register ssize_t + ssize_t i; - register double + double *squares; size_t @@ -331,7 +329,7 @@ static MagickBooleanType Classify(Image *image,short **extrema, } else { - cluster=(Cluster *) AcquireMagickMemory(sizeof(*cluster)); + cluster=(Cluster *) AcquireQuantumMemory(1,sizeof(*cluster)); head=cluster; } if (cluster == (Cluster *) NULL) @@ -340,11 +338,10 @@ static MagickBooleanType Classify(Image *image,short **extrema, /* Initialize a new class. */ - cluster->count=0; + (void) memset(cluster,0,sizeof(*cluster)); cluster->red=red; cluster->green=green; cluster->blue=blue; - cluster->next=(Cluster *) NULL; } } } @@ -353,18 +350,17 @@ static MagickBooleanType Classify(Image *image,short **extrema, /* No classes were identified-- create one. */ - cluster=(Cluster *) AcquireMagickMemory(sizeof(*cluster)); + cluster=(Cluster *) AcquireQuantumMemory(1,sizeof(*cluster)); if (cluster == (Cluster *) NULL) ThrowClassifyException(ResourceLimitError,"MemoryAllocationFailed", image->filename); /* Initialize a new class. */ - cluster->count=0; + (void) memset(cluster,0,sizeof(*cluster)); cluster->red=red; cluster->green=green; cluster->blue=blue; - cluster->next=(Cluster *) NULL; head=cluster; } /* @@ -376,10 +372,10 @@ static MagickBooleanType Classify(Image *image,short **extrema, image_view=AcquireVirtualCacheView(image,exception); for (y=0; y < (ssize_t) image->rows; y++) { - register const Quantum + const Quantum *p; - register ssize_t + ssize_t x; p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception); @@ -387,30 +383,27 @@ static MagickBooleanType Classify(Image *image,short **extrema, break; for (x=0; x < (ssize_t) image->columns; x++) { + PixelInfo + pixel; + + pixel.red=(double) ScaleQuantumToChar(GetPixelRed(image,p)); + pixel.green=(double) ScaleQuantumToChar(GetPixelGreen(image,p)); + pixel.blue=(double) ScaleQuantumToChar(GetPixelBlue(image,p)); for (cluster=head; cluster != (Cluster *) NULL; cluster=cluster->next) - if (((ssize_t) ScaleQuantumToChar(GetPixelRed(image,p)) >= - (cluster->red.left-SafeMargin)) && - ((ssize_t) ScaleQuantumToChar(GetPixelRed(image,p)) <= - (cluster->red.right+SafeMargin)) && - ((ssize_t) ScaleQuantumToChar(GetPixelGreen(image,p)) >= - (cluster->green.left-SafeMargin)) && - ((ssize_t) ScaleQuantumToChar(GetPixelGreen(image,p)) <= - (cluster->green.right+SafeMargin)) && - ((ssize_t) ScaleQuantumToChar(GetPixelBlue(image,p)) >= - (cluster->blue.left-SafeMargin)) && - ((ssize_t) ScaleQuantumToChar(GetPixelBlue(image,p)) <= - (cluster->blue.right+SafeMargin))) + if ((pixel.red >= (double) (cluster->red.left-SafeMargin)) && + (pixel.red <= (double) (cluster->red.right+SafeMargin)) && + (pixel.green >= (double) (cluster->green.left-SafeMargin)) && + (pixel.green <= (double) (cluster->green.right+SafeMargin)) && + (pixel.blue >= (double) (cluster->blue.left-SafeMargin)) && + (pixel.blue <= (double) (cluster->blue.right+SafeMargin))) { /* Count this pixel. */ count++; - cluster->red.center+=(double) ScaleQuantumToChar( - GetPixelRed(image,p)); - cluster->green.center+=(double) ScaleQuantumToChar( - GetPixelGreen(image,p)); - cluster->blue.center+=(double) ScaleQuantumToChar( - GetPixelBlue(image,p)); + cluster->red.center+=pixel.red; + cluster->green.center+=pixel.green; + cluster->blue.center+=pixel.blue; cluster->count++; break; } @@ -557,15 +550,15 @@ static MagickBooleanType Classify(Image *image,short **extrema, for (y=0; y < (ssize_t) image->rows; y++) { Cluster - *clust; + *cluster; - register const PixelInfo + const PixelInfo *magick_restrict p; - register ssize_t + ssize_t x; - register Quantum + Quantum *magick_restrict q; if (status == MagickFalse) @@ -578,30 +571,30 @@ static MagickBooleanType Classify(Image *image,short **extrema, } for (x=0; x < (ssize_t) image->columns; x++) { + PixelInfo + pixel; + SetPixelIndex(image,(Quantum) 0,q); - for (clust=head; clust != (Cluster *) NULL; clust=clust->next) + pixel.red=(double) ScaleQuantumToChar(GetPixelRed(image,q)); + pixel.green=(double) ScaleQuantumToChar(GetPixelGreen(image,q)); + pixel.blue=(double) ScaleQuantumToChar(GetPixelBlue(image,q)); + for (cluster=head; cluster != (Cluster *) NULL; cluster=cluster->next) { - if (((ssize_t) ScaleQuantumToChar(GetPixelRed(image,q)) >= - (clust->red.left-SafeMargin)) && - ((ssize_t) ScaleQuantumToChar(GetPixelRed(image,q)) <= - (clust->red.right+SafeMargin)) && - ((ssize_t) ScaleQuantumToChar(GetPixelGreen(image,q)) >= - (clust->green.left-SafeMargin)) && - ((ssize_t) ScaleQuantumToChar(GetPixelGreen(image,q)) <= - (clust->green.right+SafeMargin)) && - ((ssize_t) ScaleQuantumToChar(GetPixelBlue(image,q)) >= - (clust->blue.left-SafeMargin)) && - ((ssize_t) ScaleQuantumToChar(GetPixelBlue(image,q)) <= - (clust->blue.right+SafeMargin))) + if ((pixel.red >= (double) (cluster->red.left-SafeMargin)) && + (pixel.red <= (double) (cluster->red.right+SafeMargin)) && + (pixel.green >= (double) (cluster->green.left-SafeMargin)) && + (pixel.green <= (double) (cluster->green.right+SafeMargin)) && + (pixel.blue >= (double) (cluster->blue.left-SafeMargin)) && + (pixel.blue <= (double) (cluster->blue.right+SafeMargin))) { /* Classify this pixel. */ - SetPixelIndex(image,(Quantum) clust->id,q); + SetPixelIndex(image,(Quantum) cluster->id,q); break; } } - if (clust == (Cluster *) NULL) + if (cluster == (Cluster *) NULL) { double distance_squared, @@ -610,7 +603,7 @@ static MagickBooleanType Classify(Image *image,short **extrema, ratio, sum; - register ssize_t + ssize_t j, k; @@ -622,24 +615,18 @@ static MagickBooleanType Classify(Image *image,short **extrema, { sum=0.0; p=image->colormap+j; - distance_squared=squares[(ssize_t) ScaleQuantumToChar( - GetPixelRed(image,q))-(ssize_t) - ScaleQuantumToChar(ClampToQuantum(p->red))]+squares[(ssize_t) - ScaleQuantumToChar(GetPixelGreen(image,q))-(ssize_t) - ScaleQuantumToChar(ClampToQuantum(p->green))]+squares[(ssize_t) - ScaleQuantumToChar(GetPixelBlue(image,q))-(ssize_t) - ScaleQuantumToChar(ClampToQuantum(p->blue))]; + distance_squared= + squares[(ssize_t) (pixel.red-ScaleQuantumToChar(p->red))]+ + squares[(ssize_t) (pixel.green-ScaleQuantumToChar(p->green))]+ + squares[(ssize_t) (pixel.blue-ScaleQuantumToChar(p->blue))]; numerator=distance_squared; for (k=0; k < (ssize_t) image->colors; k++) { p=image->colormap+k; - distance_squared=squares[(ssize_t) ScaleQuantumToChar( - GetPixelRed(image,q))-(ssize_t) - ScaleQuantumToChar(ClampToQuantum(p->red))]+squares[ - (ssize_t) ScaleQuantumToChar(GetPixelGreen(image,q))-(ssize_t) - ScaleQuantumToChar(ClampToQuantum(p->green))]+squares[ - (ssize_t) ScaleQuantumToChar(GetPixelBlue(image,q))-(ssize_t) - ScaleQuantumToChar(ClampToQuantum(p->blue))]; + distance_squared= + squares[(ssize_t) (pixel.red-ScaleQuantumToChar(p->red))]+ + squares[(ssize_t) (pixel.green-ScaleQuantumToChar(p->green))]+ + squares[(ssize_t) (pixel.blue-ScaleQuantumToChar(p->blue))]; ratio=numerator/distance_squared; sum+=SegmentPower(ratio); } @@ -717,7 +704,7 @@ static MagickBooleanType Classify(Image *image,short **extrema, static void ConsolidateCrossings(ZeroCrossing *zero_crossing, const size_t number_crossings) { - register ssize_t + ssize_t i, j, k, @@ -890,7 +877,7 @@ static ssize_t DefineRegion(const short *extrema,ExtentPacket *extents) static void DerivativeHistogram(const double *histogram, double *derivative) { - register ssize_t + ssize_t i, n; @@ -967,10 +954,10 @@ MagickExport MagickBooleanType GetImageDynamicThreshold(const Image *image, double threshold; - register const Quantum + const Quantum *p; - register ssize_t + ssize_t i, x; @@ -1043,7 +1030,7 @@ MagickExport MagickBooleanType GetImageDynamicThreshold(const Image *image, } else { - cluster=(Cluster *) AcquireMagickMemory(sizeof(*cluster)); + cluster=(Cluster *) AcquireQuantumMemory(1,sizeof(*cluster)); head=cluster; } if (cluster == (Cluster *) NULL) @@ -1069,7 +1056,7 @@ MagickExport MagickBooleanType GetImageDynamicThreshold(const Image *image, /* No classes were identified-- create one. */ - cluster=(Cluster *) AcquireMagickMemory(sizeof(*cluster)); + cluster=(Cluster *) AcquireQuantumMemory(1,sizeof(*cluster)); if (cluster == (Cluster *) NULL) { (void) ThrowMagickException(exception,GetMagickModule(), @@ -1097,30 +1084,27 @@ MagickExport MagickBooleanType GetImageDynamicThreshold(const Image *image, break; for (x=0; x < (ssize_t) image->columns; x++) { + PixelInfo + pixel; + + pixel.red=(double) ScaleQuantumToChar(GetPixelRed(image,p)); + pixel.green=(double) ScaleQuantumToChar(GetPixelGreen(image,p)); + pixel.blue=(double) ScaleQuantumToChar(GetPixelBlue(image,p)); for (cluster=head; cluster != (Cluster *) NULL; cluster=cluster->next) - if (((ssize_t) ScaleQuantumToChar(GetPixelRed(image,p)) >= - (cluster->red.left-SafeMargin)) && - ((ssize_t) ScaleQuantumToChar(GetPixelRed(image,p)) <= - (cluster->red.right+SafeMargin)) && - ((ssize_t) ScaleQuantumToChar(GetPixelGreen(image,p)) >= - (cluster->green.left-SafeMargin)) && - ((ssize_t) ScaleQuantumToChar(GetPixelGreen(image,p)) <= - (cluster->green.right+SafeMargin)) && - ((ssize_t) ScaleQuantumToChar(GetPixelBlue(image,p)) >= - (cluster->blue.left-SafeMargin)) && - ((ssize_t) ScaleQuantumToChar(GetPixelBlue(image,p)) <= - (cluster->blue.right+SafeMargin))) + if ((pixel.red >= (double) (cluster->red.left-SafeMargin)) && + (pixel.red <= (double) (cluster->red.right+SafeMargin)) && + (pixel.green >= (double) (cluster->green.left-SafeMargin)) && + (pixel.green <= (double) (cluster->green.right+SafeMargin)) && + (pixel.blue >= (double) (cluster->blue.left-SafeMargin)) && + (pixel.blue <= (double) (cluster->blue.right+SafeMargin))) { /* Count this pixel. */ count++; - cluster->red.center+=(double) ScaleQuantumToChar( - GetPixelRed(image,p)); - cluster->green.center+=(double) ScaleQuantumToChar( - GetPixelGreen(image,p)); - cluster->blue.center+=(double) ScaleQuantumToChar( - GetPixelBlue(image,p)); + cluster->red.center+=pixel.red; + cluster->green.center+=pixel.green; + cluster->blue.center+=pixel.blue; cluster->count++; break; } @@ -1239,10 +1223,10 @@ MagickExport MagickBooleanType GetImageDynamicThreshold(const Image *image, static void InitializeHistogram(const Image *image,ssize_t **histogram, ExceptionInfo *exception) { - register const Quantum + const Quantum *p; - register ssize_t + ssize_t i, x; @@ -1314,7 +1298,7 @@ static void InitializeList(IntervalTree **list,ssize_t *number_nodes, static void MeanStability(IntervalTree *node) { - register IntervalTree + IntervalTree *child; if (node == (IntervalTree *) NULL) @@ -1323,10 +1307,10 @@ static void MeanStability(IntervalTree *node) child=node->child; if (child != (IntervalTree *) NULL) { - register ssize_t + ssize_t count; - register double + double sum; sum=0.0; @@ -1363,7 +1347,7 @@ static IntervalTree *InitializeIntervalTree(const ZeroCrossing *zero_crossing, *node, *root; - register ssize_t + ssize_t i; ssize_t @@ -1524,6 +1508,13 @@ static double OptimalTau(const ssize_t *histogram,const double max_tau, const double min_tau,const double delta_tau,const double smooth_threshold, short *extrema) { + double + average_tau, + *derivative, + *second_derivative, + tau, + value; + IntervalTree **list, *node, @@ -1532,14 +1523,7 @@ static double OptimalTau(const ssize_t *histogram,const double max_tau, MagickBooleanType peak; - double - average_tau, - *derivative, - *second_derivative, - tau, - value; - - register ssize_t + ssize_t i, x; @@ -1635,7 +1619,7 @@ static double OptimalTau(const ssize_t *histogram,const double max_tau, return(0.0); } /* - Find active nodes: stability is greater (or equal) to the mean stability of + Find active nodes: Stability is greater (or equal) to the mean stability of its children. */ number_nodes=0; @@ -1729,7 +1713,6 @@ static double OptimalTau(const ssize_t *histogram,const double max_tau, % of pixels for each intensity of a particular color component. % */ - static void ScaleSpace(const ssize_t *histogram,const double tau, double *scale_histogram) { @@ -1739,14 +1722,13 @@ static void ScaleSpace(const ssize_t *histogram,const double tau, *gamma, sum; - register ssize_t + ssize_t u, x; gamma=(double *) AcquireQuantumMemory(256,sizeof(*gamma)); if (gamma == (double *) NULL) - ThrowFatalException(ResourceLimitFatalError, - "UnableToAllocateGammaMap"); + ThrowFatalException(ResourceLimitFatalError,"UnableToAllocateGammaMap"); alpha=PerceptibleReciprocal(tau*sqrt(2.0*MagickPI)); beta=(-1.0*PerceptibleReciprocal(2.0*tau*tau)); for (x=0; x <= 255; x++) @@ -1820,7 +1802,7 @@ MagickExport MagickBooleanType SegmentImage(Image *image, MagickBooleanType status; - register ssize_t + ssize_t i; short @@ -1857,12 +1839,12 @@ MagickExport MagickBooleanType SegmentImage(Image *image, previous_colorspace=image->colorspace; (void) TransformImageColorspace(image,colorspace,exception); InitializeHistogram(image,histogram,exception); - (void) OptimalTau(histogram[Red],Tau,0.2,DeltaTau, - smooth_threshold == 0.0 ? 1.0 : smooth_threshold,extrema[Red]); - (void) OptimalTau(histogram[Green],Tau,0.2,DeltaTau, - smooth_threshold == 0.0 ? 1.0 : smooth_threshold,extrema[Green]); - (void) OptimalTau(histogram[Blue],Tau,0.2,DeltaTau, - smooth_threshold == 0.0 ? 1.0 : smooth_threshold,extrema[Blue]); + (void) OptimalTau(histogram[Red],Tau,0.2,DeltaTau,smooth_threshold == 0.0 ? + 1.0 : smooth_threshold,extrema[Red]); + (void) OptimalTau(histogram[Green],Tau,0.2,DeltaTau,smooth_threshold == 0.0 ? + 1.0 : smooth_threshold,extrema[Green]); + (void) OptimalTau(histogram[Blue],Tau,0.2,DeltaTau,smooth_threshold == 0.0 ? + 1.0 : smooth_threshold,extrema[Blue]); /* Classify using the fuzzy c-Means technique. */ @@ -1913,7 +1895,7 @@ MagickExport MagickBooleanType SegmentImage(Image *image, static void ZeroCrossHistogram(double *second_derivative, const double smooth_threshold,short *crossings) { - register ssize_t + ssize_t i; ssize_t |