13ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
23ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
33ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
43ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
53ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                AAA   N   N   AAA   L      Y   Y  ZZZZZ  EEEEE               %
63ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               A   A  NN  N  A   A  L       Y Y      ZZ  E                   %
73ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               AAAAA  N N N  AAAAA  L        Y     ZZZ   EEE                 %
83ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               A   A  N  NN  A   A  L        Y    ZZ     E                   %
93ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               A   A  N   N  A   A  LLLLL    Y    ZZZZZ  EEEEE               %
103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                             Analyze An Image                                %
123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                             Software Design                                 %
143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                               Bill Corbis                                   %
153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                              December 1998                                  %
163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
187ce65e7125a4e1df1a274ce373c537a9df9c16cdCristy%  Copyright 1999-2016 ImageMagick Studio LLC, a non-profit organization      %
193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  dedicated to making software imaging solutions freely available.           %
203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  You may not use this file except in compliance with the License.  You may  %
223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  obtain a copy of the License at                                            %
233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    http://www.imagemagick.org/script/license.php                            %
253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Unless required by applicable law or agreed to in writing, software        %
273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  distributed under the License is distributed on an "AS IS" BASIS,          %
283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   %
293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  See the License for the specific language governing permissions and        %
303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  limitations under the License.                                             %
313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Include declarations.
383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include <stdio.h>
403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include <stdlib.h>
413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include <string.h>
423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include <time.h>
433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include <assert.h>
443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include <math.h>
45ee67810e1107aa4480df3eb1b923f92b0a0381d0cristy#include "MagickCore/MagickCore.h"
463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   a n a l y z e I m a g e                                                   %
533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  analyzeImage() computes the brightness and saturation mean,  standard
593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  deviation, kurtosis and skewness and stores these values as attributes
603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  of the image.
613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the analyzeImage method is:
633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
64bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy%      size_t analyzeImage(Image *images,const int argc,
653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        char **argv,ExceptionInfo *exception)
663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image: the address of a structure of type Image.
703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o argc: Specifies a pointer to an integer describing the number of
723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      elements in the argument vector.
733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o argv: Specifies a pointer to a text array containing the command line
753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      arguments.
763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
80bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristyModuleExport size_t analyzeImage(Image **images,const int argc,
813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const char **argv,ExceptionInfo *exception)
823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
84151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy    text[MagickPathExtent];
853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  double
873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    area,
8848974b9e7af8f4d112ff28ec47fa3201cff2ff21cristy    brightness,
893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    brightness_mean,
903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    brightness_standard_deviation,
913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    brightness_kurtosis,
923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    brightness_skewness,
933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    brightness_sum_x,
943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    brightness_sum_x2,
953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    brightness_sum_x3,
963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    brightness_sum_x4,
9748974b9e7af8f4d112ff28ec47fa3201cff2ff21cristy    hue,
9848974b9e7af8f4d112ff28ec47fa3201cff2ff21cristy    saturation,
993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    saturation_mean,
1003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    saturation_standard_deviation,
1013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    saturation_kurtosis,
1023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    saturation_skewness,
1033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    saturation_sum_x,
1043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    saturation_sum_x2,
1053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    saturation_sum_x3,
1063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    saturation_sum_x4;
1073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
1093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
1103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(images != (Image **) NULL);
1123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(*images != (Image *) NULL);
113e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy  assert((*images)->signature == MagickCoreSignature);
1143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) argc;
1153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) argv;
1163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=(*images);
1173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  for ( ; image != (Image *) NULL; image=GetNextImageInList(image))
1183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
11948974b9e7af8f4d112ff28ec47fa3201cff2ff21cristy    CacheView
12048974b9e7af8f4d112ff28ec47fa3201cff2ff21cristy      *image_view;
12148974b9e7af8f4d112ff28ec47fa3201cff2ff21cristy
122bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    ssize_t
12348974b9e7af8f4d112ff28ec47fa3201cff2ff21cristy      y;
12448974b9e7af8f4d112ff28ec47fa3201cff2ff21cristy
12548974b9e7af8f4d112ff28ec47fa3201cff2ff21cristy    MagickBooleanType
12648974b9e7af8f4d112ff28ec47fa3201cff2ff21cristy      status;
12748974b9e7af8f4d112ff28ec47fa3201cff2ff21cristy
1283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    brightness_sum_x=0.0;
1293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    brightness_sum_x2=0.0;
1303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    brightness_sum_x3=0.0;
1313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    brightness_sum_x4=0.0;
1323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    brightness_mean=0.0;
1333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    brightness_standard_deviation=0.0;
1343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    brightness_kurtosis=0.0;
1353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    brightness_skewness=0.0;
1363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    saturation_sum_x=0.0;
1373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    saturation_sum_x2=0.0;
1383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    saturation_sum_x3=0.0;
1393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    saturation_sum_x4=0.0;
1403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    saturation_mean=0.0;
1413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    saturation_standard_deviation=0.0;
1423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    saturation_kurtosis=0.0;
1433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    saturation_skewness=0.0;
1443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    area=0.0;
14548974b9e7af8f4d112ff28ec47fa3201cff2ff21cristy    status=MagickTrue;
14646ff2676b1044ea4101ac7a59b83289cd8f6cfdacristy    image_view=AcquireVirtualCacheView(image,exception);
14748974b9e7af8f4d112ff28ec47fa3201cff2ff21cristy#if defined(MAGICKCORE_OPENMP_SUPPORT)
148ac245f8a51ea65b085d751c41d8ca4b426bdfe5bcristy    #pragma omp parallel for schedule(static,4) shared(status) \
1495e6b259130f9dbe0da4666f734937017babe573acristy      magick_threads(image,image,image->rows,1)
15048974b9e7af8f4d112ff28ec47fa3201cff2ff21cristy#endif
151bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    for (y=0; y < (ssize_t) image->rows; y++)
1523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
153ee67810e1107aa4480df3eb1b923f92b0a0381d0cristy      register const Quantum
15448974b9e7af8f4d112ff28ec47fa3201cff2ff21cristy        *p;
15548974b9e7af8f4d112ff28ec47fa3201cff2ff21cristy
156bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      register ssize_t
15748974b9e7af8f4d112ff28ec47fa3201cff2ff21cristy        x;
15848974b9e7af8f4d112ff28ec47fa3201cff2ff21cristy
15948974b9e7af8f4d112ff28ec47fa3201cff2ff21cristy      if (status == MagickFalse)
16048974b9e7af8f4d112ff28ec47fa3201cff2ff21cristy        continue;
16148974b9e7af8f4d112ff28ec47fa3201cff2ff21cristy      p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
162ee67810e1107aa4480df3eb1b923f92b0a0381d0cristy      if (p == (const Quantum *) NULL)
16348974b9e7af8f4d112ff28ec47fa3201cff2ff21cristy        {
16448974b9e7af8f4d112ff28ec47fa3201cff2ff21cristy          status=MagickFalse;
16548974b9e7af8f4d112ff28ec47fa3201cff2ff21cristy          continue;
16648974b9e7af8f4d112ff28ec47fa3201cff2ff21cristy        }
167bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      for (x=0; x < (ssize_t) image->columns; x++)
1683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
1690a39a5c567fca70403bc431d18890e89fc253eefcristy        ConvertRGBToHSL(GetPixelRed(image,p),GetPixelGreen(image,p),
170ee67810e1107aa4480df3eb1b923f92b0a0381d0cristy          GetPixelBlue(image,p),&hue,&saturation,&brightness);
1713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        brightness*=QuantumRange;
1723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        brightness_sum_x+=brightness;
1733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        brightness_sum_x2+=brightness*brightness;
1743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        brightness_sum_x3+=brightness*brightness*brightness;
1753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        brightness_sum_x4+=brightness*brightness*brightness*brightness;
1763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        saturation*=QuantumRange;
1773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        saturation_sum_x+=saturation;
1783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        saturation_sum_x2+=saturation*saturation;
1793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        saturation_sum_x3+=saturation*saturation*saturation;
1803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        saturation_sum_x4+=saturation*saturation*saturation*saturation;
1813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        area++;
1823efbdbc1a40bfa2926ec34b59cbc4de5672f1e39cristy        p+=GetPixelChannels(image);
1833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
1843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
18548974b9e7af8f4d112ff28ec47fa3201cff2ff21cristy    image_view=DestroyCacheView(image_view);
1863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (area <= 0.0)
1873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
1883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    brightness_mean=brightness_sum_x/area;
189151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy    (void) FormatLocaleString(text,MagickPathExtent,"%g",brightness_mean);
190d15e65928aec551b7388c2863de3e3e628e2e0ddcristy    (void) SetImageProperty(image,"filter:brightness:mean",text,
191d15e65928aec551b7388c2863de3e3e628e2e0ddcristy      exception);
1923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    brightness_standard_deviation=sqrt(brightness_sum_x2/area-(brightness_sum_x/
1933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      area*brightness_sum_x/area));
194151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy    (void) FormatLocaleString(text,MagickPathExtent,"%g",
1953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      brightness_standard_deviation);
196d15e65928aec551b7388c2863de3e3e628e2e0ddcristy    (void) SetImageProperty(image,"filter:brightness:standard-deviation",text,
197d15e65928aec551b7388c2863de3e3e628e2e0ddcristy      exception);
1985f07f70417e8a423f7f37d92cc84d85e114555cacristy    if (fabs(brightness_standard_deviation) >= MagickEpsilon)
1993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      brightness_kurtosis=(brightness_sum_x4/area-4.0*brightness_mean*
2003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        brightness_sum_x3/area+6.0*brightness_mean*brightness_mean*
2013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        brightness_sum_x2/area-3.0*brightness_mean*brightness_mean*
2023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        brightness_mean*brightness_mean)/(brightness_standard_deviation*
2033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        brightness_standard_deviation*brightness_standard_deviation*
2043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        brightness_standard_deviation)-3.0;
205151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy    (void) FormatLocaleString(text,MagickPathExtent,"%g",brightness_kurtosis);
206d15e65928aec551b7388c2863de3e3e628e2e0ddcristy    (void) SetImageProperty(image,"filter:brightness:kurtosis",text,
207d15e65928aec551b7388c2863de3e3e628e2e0ddcristy      exception);
2083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (brightness_standard_deviation != 0)
2093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      brightness_skewness=(brightness_sum_x3/area-3.0*brightness_mean*
2103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        brightness_sum_x2/area+2.0*brightness_mean*brightness_mean*
2113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        brightness_mean)/(brightness_standard_deviation*
2123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        brightness_standard_deviation*brightness_standard_deviation);
213151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy    (void) FormatLocaleString(text,MagickPathExtent,"%g",brightness_skewness);
214d15e65928aec551b7388c2863de3e3e628e2e0ddcristy    (void) SetImageProperty(image,"filter:brightness:skewness",text,
215d15e65928aec551b7388c2863de3e3e628e2e0ddcristy      exception);
2163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    saturation_mean=saturation_sum_x/area;
217151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy    (void) FormatLocaleString(text,MagickPathExtent,"%g",saturation_mean);
218d15e65928aec551b7388c2863de3e3e628e2e0ddcristy    (void) SetImageProperty(image,"filter:saturation:mean",text,
219d15e65928aec551b7388c2863de3e3e628e2e0ddcristy      exception);
2203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    saturation_standard_deviation=sqrt(saturation_sum_x2/area-(saturation_sum_x/
2213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      area*saturation_sum_x/area));
222151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy    (void) FormatLocaleString(text,MagickPathExtent,"%g",
2233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      saturation_standard_deviation);
224d15e65928aec551b7388c2863de3e3e628e2e0ddcristy    (void) SetImageProperty(image,"filter:saturation:standard-deviation",text,
225d15e65928aec551b7388c2863de3e3e628e2e0ddcristy      exception);
2265f07f70417e8a423f7f37d92cc84d85e114555cacristy    if (fabs(saturation_standard_deviation) >= MagickEpsilon)
2273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      saturation_kurtosis=(saturation_sum_x4/area-4.0*saturation_mean*
2283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        saturation_sum_x3/area+6.0*saturation_mean*saturation_mean*
2293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        saturation_sum_x2/area-3.0*saturation_mean*saturation_mean*
2303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        saturation_mean*saturation_mean)/(saturation_standard_deviation*
2313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        saturation_standard_deviation*saturation_standard_deviation*
2323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        saturation_standard_deviation)-3.0;
233151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy    (void) FormatLocaleString(text,MagickPathExtent,"%g",saturation_kurtosis);
234d15e65928aec551b7388c2863de3e3e628e2e0ddcristy    (void) SetImageProperty(image,"filter:saturation:kurtosis",text,
235d15e65928aec551b7388c2863de3e3e628e2e0ddcristy      exception);
2365f07f70417e8a423f7f37d92cc84d85e114555cacristy    if (fabs(saturation_standard_deviation) >= MagickEpsilon)
2373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      saturation_skewness=(saturation_sum_x3/area-3.0*saturation_mean*
2383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        saturation_sum_x2/area+2.0*saturation_mean*saturation_mean*
2393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        saturation_mean)/(saturation_standard_deviation*
2403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        saturation_standard_deviation*saturation_standard_deviation);
241151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy    (void) FormatLocaleString(text,MagickPathExtent,"%g",saturation_skewness);
242d15e65928aec551b7388c2863de3e3e628e2e0ddcristy    (void) SetImageProperty(image,"filter:saturation:skewness",text,
243d15e65928aec551b7388c2863de3e3e628e2e0ddcristy      exception);
2443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
2453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickImageFilterSignature);
2463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
247