typedef struct _PixelChannels
{
- MagickRealType
+ double
channel[CompositePixelChannel];
} PixelChannels;
length,
number_threads;
- number_threads=GetOpenMPMaximumThreads();
+ number_threads=(size_t) GetMagickResourceLimit(ThreadResource);
pixels=(PixelChannels **) AcquireQuantumMemory(number_threads,
sizeof(*pixels));
if (pixels == (PixelChannels **) NULL)
*color_1,
*color_2;
- MagickRealType
+ double
distance;
register ssize_t
color_2=(const PixelChannels *) y;
distance=0.0;
for (i=0; i < MaxPixelChannels; i++)
- distance+=color_1->channel[i]-(MagickRealType) color_2->channel[i];
+ distance+=color_1->channel[i]-(double) color_2->channel[i];
return(distance < 0 ? -1 : distance > 0 ? 1 : 0);
}
return(y);
}
-static MagickRealType ApplyEvaluateOperator(RandomInfo *random_info,
- Quantum pixel,const MagickEvaluateOperator op,const MagickRealType value)
+static double ApplyEvaluateOperator(RandomInfo *random_info,
+ Quantum pixel,const MagickEvaluateOperator op,const double value)
{
- MagickRealType
+ double
result;
result=0.0;
break;
case AbsEvaluateOperator:
{
- result=(MagickRealType) fabs((double) (pixel+value));
+ result=(double) fabs((double) (pixel+value));
break;
}
case AddEvaluateOperator:
{
- result=(MagickRealType) (pixel+value);
+ result=(double) (pixel+value);
break;
}
case AddModulusEvaluateOperator:
}
case AndEvaluateOperator:
{
- result=(MagickRealType) ((size_t) pixel & (size_t) (value+0.5));
+ result=(double) ((size_t) pixel & (size_t) (value+0.5));
break;
}
case CosineEvaluateOperator:
{
- result=(MagickRealType) (QuantumRange*(0.5*cos((double) (2.0*MagickPI*
+ result=(double) (QuantumRange*(0.5*cos((double) (2.0*MagickPI*
QuantumScale*pixel*value))+0.5));
break;
}
}
case ExponentialEvaluateOperator:
{
- result=(MagickRealType) (QuantumRange*exp((double) (value*QuantumScale*
+ result=(double) (QuantumRange*exp((double) (value*QuantumScale*
pixel)));
break;
}
case GaussianNoiseEvaluateOperator:
{
- result=(MagickRealType) GenerateDifferentialNoise(random_info,pixel,
+ result=(double) GenerateDifferentialNoise(random_info,pixel,
GaussianNoise,value);
break;
}
case ImpulseNoiseEvaluateOperator:
{
- result=(MagickRealType) GenerateDifferentialNoise(random_info,pixel,
+ result=(double) GenerateDifferentialNoise(random_info,pixel,
ImpulseNoise,value);
break;
}
case LaplacianNoiseEvaluateOperator:
{
- result=(MagickRealType) GenerateDifferentialNoise(random_info,pixel,
+ result=(double) GenerateDifferentialNoise(random_info,pixel,
LaplacianNoise,value);
break;
}
case LeftShiftEvaluateOperator:
{
- result=(MagickRealType) ((size_t) pixel << (size_t) (value+0.5));
+ result=(double) ((size_t) pixel << (size_t) (value+0.5));
break;
}
case LogEvaluateOperator:
{
- result=(MagickRealType) (QuantumRange*log((double) (QuantumScale*value*
- pixel+1.0))/log((double) (value+1.0)));
+ if ((QuantumScale*pixel) >= MagickEpsilon)
+ result=(double) (QuantumRange*log((double) (QuantumScale*value*
+ pixel+1.0))/log((double) (value+1.0)));
break;
}
case MaxEvaluateOperator:
{
- result=(MagickRealType) EvaluateMax((double) pixel,value);
+ result=(double) EvaluateMax((double) pixel,value);
break;
}
case MeanEvaluateOperator:
{
- result=(MagickRealType) (pixel+value);
+ result=(double) (pixel+value);
break;
}
case MedianEvaluateOperator:
{
- result=(MagickRealType) (pixel+value);
+ result=(double) (pixel+value);
break;
}
case MinEvaluateOperator:
{
- result=(MagickRealType) MagickMin((double) pixel,value);
+ result=(double) MagickMin((double) pixel,value);
break;
}
case MultiplicativeNoiseEvaluateOperator:
{
- result=(MagickRealType) GenerateDifferentialNoise(random_info,pixel,
+ result=(double) GenerateDifferentialNoise(random_info,pixel,
MultiplicativeGaussianNoise,value);
break;
}
case MultiplyEvaluateOperator:
{
- result=(MagickRealType) (value*pixel);
+ result=(double) (value*pixel);
break;
}
case OrEvaluateOperator:
{
- result=(MagickRealType) ((size_t) pixel | (size_t) (value+0.5));
+ result=(double) ((size_t) pixel | (size_t) (value+0.5));
break;
}
case PoissonNoiseEvaluateOperator:
{
- result=(MagickRealType) GenerateDifferentialNoise(random_info,pixel,
+ result=(double) GenerateDifferentialNoise(random_info,pixel,
PoissonNoise,value);
break;
}
case PowEvaluateOperator:
{
- result=(MagickRealType) (QuantumRange*pow((double) (QuantumScale*pixel),
+ result=(double) (QuantumRange*pow((double) (QuantumScale*pixel),
(double) value));
break;
}
case RightShiftEvaluateOperator:
{
- result=(MagickRealType) ((size_t) pixel >> (size_t) (value+0.5));
+ result=(double) ((size_t) pixel >> (size_t) (value+0.5));
break;
}
case SetEvaluateOperator:
}
case SineEvaluateOperator:
{
- result=(MagickRealType) (QuantumRange*(0.5*sin((double) (2.0*MagickPI*
+ result=(double) (QuantumRange*(0.5*sin((double) (2.0*MagickPI*
QuantumScale*pixel*value))+0.5));
break;
}
case SubtractEvaluateOperator:
{
- result=(MagickRealType) (pixel-value);
+ result=(double) (pixel-value);
break;
}
case SumEvaluateOperator:
{
- result=(MagickRealType) (pixel+value);
+ result=(double) (pixel+value);
break;
}
case ThresholdEvaluateOperator:
{
- result=(MagickRealType) (((MagickRealType) pixel <= value) ? 0 :
+ result=(double) (((double) pixel <= value) ? 0 :
QuantumRange);
break;
}
case ThresholdBlackEvaluateOperator:
{
- result=(MagickRealType) (((MagickRealType) pixel <= value) ? 0 : pixel);
+ result=(double) (((double) pixel <= value) ? 0 : pixel);
break;
}
case ThresholdWhiteEvaluateOperator:
{
- result=(MagickRealType) (((MagickRealType) pixel > value) ? QuantumRange :
+ result=(double) (((double) pixel > value) ? QuantumRange :
pixel);
break;
}
case UniformNoiseEvaluateOperator:
{
- result=(MagickRealType) GenerateDifferentialNoise(random_info,pixel,
+ result=(double) GenerateDifferentialNoise(random_info,pixel,
UniformNoise,value);
break;
}
case XorEvaluateOperator:
{
- result=(MagickRealType) ((size_t) pixel ^ (size_t) (value+0.5));
+ result=(double) ((size_t) pixel ^ (size_t) (value+0.5));
break;
}
}
*next;
Image
- *evaluate_image;
+ *image;
MagickBooleanType
status;
/*
Initialize evaluate next attributes.
*/
- evaluate_image=CloneImage(images,images->columns,images->rows,MagickTrue,
+ image=CloneImage(images,images->columns,images->rows,MagickTrue,
exception);
- if (evaluate_image == (Image *) NULL)
+ if (image == (Image *) NULL)
return((Image *) NULL);
- if (SetImageStorageClass(evaluate_image,DirectClass,exception) == MagickFalse)
+ if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
{
- evaluate_image=DestroyImage(evaluate_image);
+ image=DestroyImage(image);
return((Image *) NULL);
}
number_images=GetImageListLength(images);
evaluate_pixels=AcquirePixelThreadSet(images,number_images);
if (evaluate_pixels == (PixelChannels **) NULL)
{
- evaluate_image=DestroyImage(evaluate_image);
+ image=DestroyImage(image);
(void) ThrowMagickException(exception,GetMagickModule(),
ResourceLimitError,"MemoryAllocationFailed","'%s'",images->filename);
return((Image *) NULL);
progress=0;
random_info=AcquireRandomInfoThreadSet();
key=GetRandomSecretKey(random_info[0]);
- evaluate_view=AcquireAuthenticCacheView(evaluate_image,exception);
+ evaluate_view=AcquireAuthenticCacheView(image,exception);
if (op == MedianEvaluateOperator)
{
#if defined(MAGICKCORE_OPENMP_SUPPORT)
#pragma omp parallel for schedule(static) shared(progress,status) \
- dynamic_number_threads(images->columns,images->rows,key == ~0UL)
+ dynamic_number_threads(image,image->columns,image->rows,key == ~0UL)
#endif
- for (y=0; y < (ssize_t) evaluate_image->rows; y++)
+ for (y=0; y < (ssize_t) image->rows; y++)
{
CacheView
*image_view;
if (status == MagickFalse)
continue;
q=QueueCacheViewAuthenticPixels(evaluate_view,0,y,
- evaluate_image->columns,1,exception);
+ image->columns,1,exception);
if (q == (Quantum *) NULL)
{
status=MagickFalse;
continue;
}
evaluate_pixel=evaluate_pixels[id];
- for (x=0; x < (ssize_t) evaluate_image->columns; x++)
+ for (x=0; x < (ssize_t) image->columns; x++)
{
register ssize_t
j,
image_view=DestroyCacheView(image_view);
break;
}
- for (i=0; i < (ssize_t) GetPixelChannels(evaluate_image); i++)
+ for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
{
PixelChannel
channel;
evaluate_traits,
traits;
- channel=GetPixelChannelMapChannel(evaluate_image,i);
- evaluate_traits=GetPixelChannelMapTraits(evaluate_image,channel);
- traits=GetPixelChannelMapTraits(next,channel);
+ channel=GetPixelChannelChannel(image,i);
+ evaluate_traits=GetPixelChannelTraits(image,channel);
+ traits=GetPixelChannelTraits(next,channel);
if ((traits == UndefinedPixelTrait) ||
(evaluate_traits == UndefinedPixelTrait))
continue;
if ((evaluate_traits & UpdatePixelTrait) == 0)
continue;
evaluate_pixel[j].channel[i]=ApplyEvaluateOperator(
- random_info[id],GetPixelChannel(evaluate_image,channel,p),op,
+ random_info[id],GetPixelChannel(image,channel,p),op,
evaluate_pixel[j].channel[i]);
}
image_view=DestroyCacheView(image_view);
}
qsort((void *) evaluate_pixel,number_images,sizeof(*evaluate_pixel),
IntensityCompare);
- for (k=0; k < (ssize_t) GetPixelChannels(evaluate_image); k++)
+ for (k=0; k < (ssize_t) GetPixelChannels(image); k++)
q[k]=ClampToQuantum(evaluate_pixel[j/2].channel[k]);
- q+=GetPixelChannels(evaluate_image);
+ q+=GetPixelChannels(image);
}
if (SyncCacheViewAuthenticPixels(evaluate_view,exception) == MagickFalse)
status=MagickFalse;
#pragma omp critical (MagickCore_EvaluateImages)
#endif
proceed=SetImageProgress(images,EvaluateImageTag,progress++,
- evaluate_image->rows);
+ image->rows);
if (proceed == MagickFalse)
status=MagickFalse;
}
{
#if defined(MAGICKCORE_OPENMP_SUPPORT)
#pragma omp parallel for schedule(static) shared(progress,status) \
- dynamic_number_threads(images->columns,images->rows,key == ~0UL)
+ dynamic_number_threads(image,image->columns,image->rows,key == ~0UL)
#endif
- for (y=0; y < (ssize_t) evaluate_image->rows; y++)
+ for (y=0; y < (ssize_t) image->rows; y++)
{
CacheView
*image_view;
if (status == MagickFalse)
continue;
q=QueueCacheViewAuthenticPixels(evaluate_view,0,y,
- evaluate_image->columns,1,exception);
+ image->columns,1,exception);
if (q == (Quantum *) NULL)
{
status=MagickFalse;
continue;
}
evaluate_pixel=evaluate_pixels[id];
- for (j=0; j < (ssize_t) evaluate_image->columns; j++)
+ for (j=0; j < (ssize_t) image->columns; j++)
for (i=0; i < MaxPixelChannels; i++)
evaluate_pixel[j].channel[i]=0.0;
next=images;
evaluate_traits,
traits;
- channel=GetPixelChannelMapChannel(evaluate_image,i);
- traits=GetPixelChannelMapTraits(next,channel);
- evaluate_traits=GetPixelChannelMapTraits(evaluate_image,channel);
+ channel=GetPixelChannelChannel(image,i);
+ traits=GetPixelChannelTraits(next,channel);
+ evaluate_traits=GetPixelChannelTraits(image,channel);
if ((traits == UndefinedPixelTrait) ||
(evaluate_traits == UndefinedPixelTrait))
continue;
if ((traits & UpdatePixelTrait) == 0)
continue;
evaluate_pixel[x].channel[i]=ApplyEvaluateOperator(
- random_info[id],GetPixelChannel(evaluate_image,channel,p),j ==
+ random_info[id],GetPixelChannel(image,channel,p),j ==
0 ? AddEvaluateOperator : op,evaluate_pixel[x].channel[i]);
}
p+=GetPixelChannels(next);
image_view=DestroyCacheView(image_view);
next=GetNextImageInList(next);
}
- for (x=0; x < (ssize_t) evaluate_image->columns; x++)
+ for (x=0; x < (ssize_t) image->columns; x++)
{
register ssize_t
i;
{
case MeanEvaluateOperator:
{
- for (i=0; i < (ssize_t) GetPixelChannels(evaluate_image); i++)
- evaluate_pixel[x].channel[i]/=(MagickRealType) number_images;
+ for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
+ evaluate_pixel[x].channel[i]/=(double) number_images;
break;
}
case MultiplyEvaluateOperator:
{
- for (i=0; i < (ssize_t) GetPixelChannels(evaluate_image); i++)
+ for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
{
register ssize_t
j;
break;
}
}
- for (x=0; x < (ssize_t) evaluate_image->columns; x++)
+ for (x=0; x < (ssize_t) image->columns; x++)
{
register ssize_t
i;
- if (GetPixelMask(evaluate_image,q) != 0)
+ if (GetPixelMask(image,q) != 0)
{
- q+=GetPixelChannels(evaluate_image);
+ q+=GetPixelChannels(image);
continue;
}
- for (i=0; i < (ssize_t) GetPixelChannels(evaluate_image); i++)
+ for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
{
PixelChannel
channel;
PixelTrait
traits;
- channel=GetPixelChannelMapChannel(evaluate_image,i);
- traits=GetPixelChannelMapTraits(evaluate_image,channel);
+ channel=GetPixelChannelChannel(image,i);
+ traits=GetPixelChannelTraits(image,channel);
if (traits == UndefinedPixelTrait)
continue;
if ((traits & UpdatePixelTrait) == 0)
continue;
q[i]=ClampToQuantum(evaluate_pixel[x].channel[i]);
}
- q+=GetPixelChannels(evaluate_image);
+ q+=GetPixelChannels(image);
}
if (SyncCacheViewAuthenticPixels(evaluate_view,exception) == MagickFalse)
status=MagickFalse;
#pragma omp critical (MagickCore_EvaluateImages)
#endif
proceed=SetImageProgress(images,EvaluateImageTag,progress++,
- evaluate_image->rows);
+ image->rows);
if (proceed == MagickFalse)
status=MagickFalse;
}
evaluate_pixels=DestroyPixelThreadSet(evaluate_pixels);
random_info=DestroyRandomInfoThreadSet(random_info);
if (status == MagickFalse)
- evaluate_image=DestroyImage(evaluate_image);
- return(evaluate_image);
+ image=DestroyImage(image);
+ return(image);
}
MagickExport MagickBooleanType EvaluateImage(Image *image,
image_view=AcquireAuthenticCacheView(image,exception);
#if defined(MAGICKCORE_OPENMP_SUPPORT)
#pragma omp parallel for schedule(static,4) shared(progress,status) \
- dynamic_number_threads(image->columns,image->rows,key == ~0UL)
+ dynamic_number_threads(image,image->columns,image->rows,key == ~0UL)
#endif
for (y=0; y < (ssize_t) image->rows; y++)
{
register ssize_t
i;
- if (GetPixelMask(image,q) != 0)
- {
- q+=GetPixelChannels(image);
- continue;
- }
for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
{
PixelChannel
PixelTrait
traits;
- channel=GetPixelChannelMapChannel(image,i);
- traits=GetPixelChannelMapTraits(image,channel);
+ channel=GetPixelChannelChannel(image,i);
+ traits=GetPixelChannelTraits(image,channel);
if (traits == UndefinedPixelTrait)
continue;
- if ((traits & CopyPixelTrait) != 0)
+ if (((traits & CopyPixelTrait) != 0) ||
+ (GetPixelMask(image,q) != 0))
continue;
q[i]=ClampToQuantum(ApplyEvaluateOperator(random_info[id],q[i],op,
value));
const size_t number_parameters,const double *parameters,
ExceptionInfo *exception)
{
- MagickRealType
+ double
result;
register ssize_t
}
case SinusoidFunction:
{
- MagickRealType
+ double
amplitude,
bias,
frequency,
phase=(number_parameters >= 2) ? parameters[1] : 0.0;
amplitude=(number_parameters >= 3) ? parameters[2] : 0.5;
bias=(number_parameters >= 4) ? parameters[3] : 0.5;
- result=(MagickRealType) (QuantumRange*(amplitude*sin((double) (2.0*
+ result=(double) (QuantumRange*(amplitude*sin((double) (2.0*
MagickPI*(frequency*QuantumScale*pixel+phase/360.0)))+bias));
break;
}
case ArcsinFunction:
{
- MagickRealType
+ double
bias,
center,
range,
if (result >= 1.0)
result=bias+range/2.0;
else
- result=(MagickRealType) (range/MagickPI*asin((double) result)+bias);
+ result=(double) (range/MagickPI*asin((double) result)+bias);
result*=QuantumRange;
break;
}
case ArctanFunction:
{
- MagickRealType
+ double
center,
bias,
range,
center=(number_parameters >= 2) ? parameters[1] : 0.5;
range=(number_parameters >= 3) ? parameters[2] : 1.0;
bias=(number_parameters >= 4) ? parameters[3] : 0.5;
- result=(MagickRealType) (MagickPI*slope*(QuantumScale*pixel-center));
- result=(MagickRealType) (QuantumRange*(range/MagickPI*atan((double)
+ result=(double) (MagickPI*slope*(QuantumScale*pixel-center));
+ result=(double) (QuantumRange*(range/MagickPI*atan((double)
result)+bias));
break;
}
image_view=AcquireAuthenticCacheView(image,exception);
#if defined(MAGICKCORE_OPENMP_SUPPORT)
#pragma omp parallel for schedule(static,4) shared(progress,status) \
- dynamic_number_threads(image->columns,image->rows,1)
+ dynamic_number_threads(image,image->columns,image->rows,1)
#endif
for (y=0; y < (ssize_t) image->rows; y++)
{
PixelTrait
traits;
- channel=GetPixelChannelMapChannel(image,i);
- traits=GetPixelChannelMapTraits(image,channel);
+ channel=GetPixelChannelChannel(image,i);
+ traits=GetPixelChannelTraits(image,channel);
if (traits == UndefinedPixelTrait)
continue;
if ((traits & UpdatePixelTrait) == 0)
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
-% GetImageMean() returns the mean and standard deviation of one or more
-% image channels.
+% GetImageMean() returns the mean and standard deviation of one or more image
+% channels.
%
% The format of the GetImageMean method is:
%
MagickExport MagickBooleanType GetImageMean(const Image *image,double *mean,
double *standard_deviation,ExceptionInfo *exception)
{
+ double
+ area;
+
ChannelStatistics
*channel_statistics;
register ssize_t
i;
- size_t
- area;
-
assert(image != (Image *) NULL);
assert(image->signature == MagickSignature);
if (image->debug != MagickFalse)
channel_statistics=GetImageStatistics(image,exception);
if (channel_statistics == (ChannelStatistics *) NULL)
return(MagickFalse);
- area=0;
+ area=0.0;
channel_statistics[CompositePixelChannel].mean=0.0;
channel_statistics[CompositePixelChannel].standard_deviation=0.0;
for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
PixelTrait
traits;
- channel=GetPixelChannelMapChannel(image,i);
- traits=GetPixelChannelMapTraits(image,channel);
+ channel=GetPixelChannelChannel(image,i);
+ traits=GetPixelChannelTraits(image,channel);
if (traits == UndefinedPixelTrait)
continue;
if ((traits & UpdatePixelTrait) == 0)
image_view=AcquireVirtualCacheView(image,exception);
#if defined(MAGICKCORE_OPENMP_SUPPORT)
#pragma omp parallel for schedule(static) shared(status) \
- dynamic_number_threads(image->columns,image->rows,1)
+ dynamic_number_threads(image,image->columns,image->rows,1)
#endif
for (y=0; y < (ssize_t) image->rows; y++)
{
register ssize_t
i;
- if (GetPixelMask(image,p) != 0)
- {
- p+=GetPixelChannels(image);
- continue;
- }
for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
{
PixelChannel
PixelTrait
traits;
- channel=GetPixelChannelMapChannel(image,i);
- traits=GetPixelChannelMapTraits(image,channel);
+ channel=GetPixelChannelChannel(image,i);
+ traits=GetPixelChannelTraits(image,channel);
if (traits == UndefinedPixelTrait)
continue;
- if ((traits & UpdatePixelTrait) == 0)
+ if (((traits & UpdatePixelTrait) == 0) ||
+ (GetPixelMask(image,p) != 0))
continue;
#if defined(MAGICKCORE_OPENMP_SUPPORT)
#pragma omp critical (MagickCore_GetImageKurtosis)
*image_view;
MagickBooleanType
+ initialize,
status;
ssize_t
if (image->debug != MagickFalse)
(void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
status=MagickTrue;
- *maxima=(-MagickHuge);
- *minima=MagickHuge;
+ initialize=MagickTrue;
+ *maxima=0.0;
+ *minima=0.0;
image_view=AcquireVirtualCacheView(image,exception);
#if defined(MAGICKCORE_OPENMP_SUPPORT)
- #pragma omp parallel for schedule(static) shared(status) \
- dynamic_number_threads(image->columns,image->rows,1)
+ #pragma omp parallel for schedule(static) shared(status,initialize) \
+ dynamic_number_threads(image,image->columns,image->rows,1)
#endif
for (y=0; y < (ssize_t) image->rows; y++)
{
PixelTrait
traits;
- channel=GetPixelChannelMapChannel(image,i);
- traits=GetPixelChannelMapTraits(image,channel);
+ channel=GetPixelChannelChannel(image,i);
+ traits=GetPixelChannelTraits(image,channel);
if (traits == UndefinedPixelTrait)
continue;
if ((traits & UpdatePixelTrait) == 0)
#pragma omp critical (MagickCore_GetImageRange)
#endif
{
- if ((double) p[i] < *minima)
- *minima=(double) p[i];
- if ((double) p[i] > *maxima)
- *maxima=(double) p[i];
+ if (initialize != MagickFalse)
+ {
+ *minima=(double) p[i];
+ *maxima=(double) p[i];
+ initialize=MagickFalse;
+ }
+ else
+ {
+ if ((double) p[i] < *minima)
+ *minima=(double) p[i];
+ if ((double) p[i] > *maxima)
+ *maxima=(double) p[i];
+ }
}
}
p+=GetPixelChannels(image);
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
-% GetImageStatistics() returns statistics for each channel in the
-% image. The statistics include the channel depth, its minima, maxima, mean,
-% standard deviation, kurtosis and skewness. You can access the red channel
-% mean, for example, like this:
+% GetImageStatistics() returns statistics for each channel in the image. The
+% statistics include the channel depth, its minima, maxima, mean, standard
+% deviation, kurtosis and skewness. You can access the red channel mean, for
+% example, like this:
%
% channel_statistics=GetImageStatistics(image,exception);
% red_mean=channel_statistics[RedPixelChannel].mean;
PixelTrait
traits;
- channel=GetPixelChannelMapChannel(image,i);
- traits=GetPixelChannelMapTraits(image,channel);
+ channel=GetPixelChannelChannel(image,i);
+ traits=GetPixelChannelTraits(image,channel);
if ((traits & UpdatePixelTrait) != 0)
channels++;
}
ChannelStatistics
*channel_statistics;
- double
- area;
-
MagickStatusType
status;
PixelTrait
traits;
- channel=GetPixelChannelMapChannel(image,i);
- traits=GetPixelChannelMapTraits(image,channel);
+ channel=GetPixelChannelChannel(image,i);
+ traits=GetPixelChannelTraits(image,channel);
if (traits == UndefinedPixelTrait)
continue;
if (channel_statistics[channel].depth != MAGICKCORE_QUANTUM_DEPTH)
if (status != MagickFalse)
{
channel_statistics[channel].depth++;
+ i--;
continue;
}
}
channel_statistics[channel].sum_cubed+=(double) p[i]*p[i]*p[i];
channel_statistics[channel].sum_fourth_power+=(double) p[i]*p[i]*p[i]*
p[i];
+ channel_statistics[channel].area++;
}
p+=GetPixelChannels(image);
}
}
- area=(double) image->columns*image->rows;
for (i=0; i < (ssize_t) MaxPixelChannels; i++)
{
- channel_statistics[i].sum/=area;
- channel_statistics[i].sum_squared/=area;
- channel_statistics[i].sum_cubed/=area;
- channel_statistics[i].sum_fourth_power/=area;
+ double
+ area;
+
+ area=MagickEpsilonReciprocal(channel_statistics[i].area);
+ channel_statistics[i].sum*=area;
+ channel_statistics[i].sum_squared*=area;
+ channel_statistics[i].sum_cubed*=area;
+ channel_statistics[i].sum_fourth_power*=area;
channel_statistics[i].mean=channel_statistics[i].sum;
channel_statistics[i].variance=channel_statistics[i].sum_squared;
channel_statistics[i].standard_deviation=sqrt(
channel_statistics[CompositePixelChannel].skewness/=channels;
for (i=0; i <= (ssize_t) MaxPixelChannels; i++)
{
- if (channel_statistics[i].standard_deviation == 0.0)
- continue;
+ double
+ standard_deviation;
+
+ standard_deviation=MagickEpsilonReciprocal(
+ channel_statistics[i].standard_deviation);
channel_statistics[i].skewness=(channel_statistics[i].sum_cubed-3.0*
channel_statistics[i].mean*channel_statistics[i].sum_squared+2.0*
channel_statistics[i].mean*channel_statistics[i].mean*
- channel_statistics[i].mean)/(channel_statistics[i].standard_deviation*
- channel_statistics[i].standard_deviation*
- channel_statistics[i].standard_deviation);
+ channel_statistics[i].mean)*(standard_deviation*standard_deviation*
+ standard_deviation);
channel_statistics[i].kurtosis=(channel_statistics[i].sum_fourth_power-4.0*
channel_statistics[i].mean*channel_statistics[i].sum_cubed+6.0*
channel_statistics[i].mean*channel_statistics[i].mean*
channel_statistics[i].sum_squared-3.0*channel_statistics[i].mean*
channel_statistics[i].mean*1.0*channel_statistics[i].mean*
- channel_statistics[i].mean)/(channel_statistics[i].standard_deviation*
- channel_statistics[i].standard_deviation*
- channel_statistics[i].standard_deviation*
- channel_statistics[i].standard_deviation)-3.0;
+ channel_statistics[i].mean)*(standard_deviation*standard_deviation*
+ standard_deviation*standard_deviation)-3.0;
}
return(channel_statistics);
}
size_t
number_threads;
- number_threads=GetOpenMPMaximumThreads();
+ number_threads=(size_t) GetMagickResourceLimit(ThreadResource);
pixel_list=(PixelList **) AcquireQuantumMemory(number_threads,
sizeof(*pixel_list));
if (pixel_list == (PixelList **) NULL)
static inline void GetMeanPixelList(PixelList *pixel_list,Quantum *pixel)
{
- MagickRealType
+ double
sum;
register SkipList
do
{
color=p->nodes[color].next[0];
- sum+=(MagickRealType) p->nodes[color].count*color;
+ sum+=(double) p->nodes[color].count*color;
count+=p->nodes[color].count;
} while (count < (ssize_t) pixel_list->length);
sum/=pixel_list->length;
static inline void GetStandardDeviationPixelList(PixelList *pixel_list,
Quantum *pixel)
{
- MagickRealType
+ double
sum,
sum_squared;
i;
color=p->nodes[color].next[0];
- sum+=(MagickRealType) p->nodes[color].count*color;
+ sum+=(double) p->nodes[color].count*color;
for (i=0; i < (ssize_t) p->nodes[color].count; i++)
- sum_squared+=((MagickRealType) color)*((MagickRealType) color);
+ sum_squared+=((double) color)*((double) color);
count+=p->nodes[color].count;
} while (count < (ssize_t) pixel_list->length);
sum/=pixel_list->length;
AddNodePixelList(pixel_list,index);
}
-static inline MagickRealType MagickAbsoluteValue(const MagickRealType x)
+static inline double MagickAbsoluteValue(const double x)
{
if (x < 0)
return(-x);
statistic_view=AcquireAuthenticCacheView(statistic_image,exception);
#if defined(MAGICKCORE_OPENMP_SUPPORT)
#pragma omp parallel for schedule(static,4) shared(progress,status) \
- dynamic_number_threads(image->columns,image->rows,1)
+ dynamic_number_threads(image,image->columns,image->rows,1)
#endif
for (y=0; y < (ssize_t) statistic_image->rows; y++)
{
register ssize_t
i;
- if (GetPixelMask(image,p) != 0)
- {
- p+=GetPixelChannels(image);
- q+=GetPixelChannels(statistic_image);
- continue;
- }
for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
{
PixelChannel
ssize_t
v;
- channel=GetPixelChannelMapChannel(image,i);
- traits=GetPixelChannelMapTraits(image,channel);
- statistic_traits=GetPixelChannelMapTraits(statistic_image,channel);
+ channel=GetPixelChannelChannel(image,i);
+ traits=GetPixelChannelTraits(image,channel);
+ statistic_traits=GetPixelChannelTraits(statistic_image,channel);
if ((traits == UndefinedPixelTrait) ||
(statistic_traits == UndefinedPixelTrait))
continue;
- if ((statistic_traits & CopyPixelTrait) != 0)
+ if (((statistic_traits & CopyPixelTrait) != 0) ||
+ (GetPixelMask(image,p) != 0))
{
SetPixelChannel(statistic_image,channel,p[center+i],q);
continue;
{
case GradientStatistic:
{
- MagickRealType
+ double
maximum,
minimum;
GetMinimumPixelList(pixel_list[id],&pixel);
- minimum=(MagickRealType) pixel;
+ minimum=(double) pixel;
GetMaximumPixelList(pixel_list[id],&pixel);
- maximum=(MagickRealType) pixel;
+ maximum=(double) pixel;
pixel=ClampToQuantum(MagickAbsoluteValue(maximum-minimum));
break;
}