13ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* 23ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 33ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 43ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 53ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 63ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% SSSSS TTTTT AAA TTTTT IIIII SSSSS TTTTT IIIII CCCC % 73ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% SS T A A T I SS T I C % 83ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% SSS T AAAAA T I SSS T I C % 93ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% SS T A A T I SS T I C % 103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% SSSSS T A A T IIIII SSSSS T IIIII CCCC % 113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 133e2860cb0796fe77659325ec3d540d8766d54f49cristy% MagickCore Image Statistical Methods % 143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% Software Design % 16de984cdc3631106b1cbbb8d3972b76a0fc27e8e8cristy% Cristy % 173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% July 1992 % 183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 207ce65e7125a4e1df1a274ce373c537a9df9c16cdCristy% Copyright 1999-2016 ImageMagick Studio LLC, a non-profit organization % 213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% dedicated to making software imaging solutions freely available. % 223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% You may not use this file except in compliance with the License. You may % 243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% obtain a copy of the License at % 253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% http://www.imagemagick.org/script/license.php % 273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% Unless required by applicable law or agreed to in writing, software % 293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% distributed under the License is distributed on an "AS IS" BASIS, % 303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. % 313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% See the License for the specific language governing permissions and % 323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% limitations under the License. % 333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/ 393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* 413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Include declarations. 423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/ 434c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/studio.h" 444c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/property.h" 45eeec14f738e8dbcfa064c1158a6e503b30a5dc3edirk#include "MagickCore/accelerate-private.h" 464c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/animate.h" 474c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/blob.h" 484c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/blob-private.h" 494c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/cache.h" 504c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/cache-private.h" 514c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/cache-view.h" 524c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/client.h" 534c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/color.h" 544c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/color-private.h" 554c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/colorspace.h" 564c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/colorspace-private.h" 574c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/composite.h" 584c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/composite-private.h" 594c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/compress.h" 604c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/constitute.h" 614c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/display.h" 624c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/draw.h" 634c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/enhance.h" 644c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/exception.h" 654c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/exception-private.h" 664c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/gem.h" 678ea81224e9ff022e56eb2cddb12860a8b2e90411cristy#include "MagickCore/gem-private.h" 684c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/geometry.h" 694c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/list.h" 704c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/image-private.h" 714c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/magic.h" 724c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/magick.h" 734c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/memory_.h" 744c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/module.h" 754c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/monitor.h" 764c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/monitor-private.h" 774c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/option.h" 784c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/paint.h" 794c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/pixel-accessor.h" 804c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/profile.h" 814c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/quantize.h" 824c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/quantum-private.h" 834c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/random_.h" 844c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/random-private.h" 8557340e008c81f05c0adb4d8874dda11104d8bb7ecristy#include "MagickCore/resource_.h" 864c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/segment.h" 874c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/semaphore.h" 884c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/signature-private.h" 894c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/statistic.h" 904c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/string_.h" 914c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/thread-private.h" 924c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/timer.h" 934c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/utility.h" 944c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/version.h" 953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* 973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 1003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 101d18ae7ce9b6ff934472abb8e3fa73d0c1aed7d20cristy% E v a l u a t e I m a g e % 102316d51773c093e74e15de805e8bf620d6b56bc8bcristy% % 103316d51773c093e74e15de805e8bf620d6b56bc8bcristy% % 104316d51773c093e74e15de805e8bf620d6b56bc8bcristy% % 105316d51773c093e74e15de805e8bf620d6b56bc8bcristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 106316d51773c093e74e15de805e8bf620d6b56bc8bcristy% 107d18ae7ce9b6ff934472abb8e3fa73d0c1aed7d20cristy% EvaluateImage() applies a value to the image with an arithmetic, relational, 108d18ae7ce9b6ff934472abb8e3fa73d0c1aed7d20cristy% or logical operator to an image. Use these operations to lighten or darken 109d18ae7ce9b6ff934472abb8e3fa73d0c1aed7d20cristy% an image, to increase or decrease contrast in an image, or to produce the 110d18ae7ce9b6ff934472abb8e3fa73d0c1aed7d20cristy% "negative" of an image. 111316d51773c093e74e15de805e8bf620d6b56bc8bcristy% 112d42d995b9cb2a16e13221e665554417a5b7ec7fbcristy% The format of the EvaluateImage method is: 113316d51773c093e74e15de805e8bf620d6b56bc8bcristy% 114d18ae7ce9b6ff934472abb8e3fa73d0c1aed7d20cristy% MagickBooleanType EvaluateImage(Image *image, 115d18ae7ce9b6ff934472abb8e3fa73d0c1aed7d20cristy% const MagickEvaluateOperator op,const double value, 116d18ae7ce9b6ff934472abb8e3fa73d0c1aed7d20cristy% ExceptionInfo *exception) 117d18ae7ce9b6ff934472abb8e3fa73d0c1aed7d20cristy% MagickBooleanType EvaluateImages(Image *images, 118d18ae7ce9b6ff934472abb8e3fa73d0c1aed7d20cristy% const MagickEvaluateOperator op,const double value, 119d18ae7ce9b6ff934472abb8e3fa73d0c1aed7d20cristy% ExceptionInfo *exception) 120316d51773c093e74e15de805e8bf620d6b56bc8bcristy% 121316d51773c093e74e15de805e8bf620d6b56bc8bcristy% A description of each parameter follows: 122316d51773c093e74e15de805e8bf620d6b56bc8bcristy% 123d18ae7ce9b6ff934472abb8e3fa73d0c1aed7d20cristy% o image: the image. 124d18ae7ce9b6ff934472abb8e3fa73d0c1aed7d20cristy% 125d18ae7ce9b6ff934472abb8e3fa73d0c1aed7d20cristy% o op: A channel op. 126d18ae7ce9b6ff934472abb8e3fa73d0c1aed7d20cristy% 127d18ae7ce9b6ff934472abb8e3fa73d0c1aed7d20cristy% o value: A value value. 128316d51773c093e74e15de805e8bf620d6b56bc8bcristy% 129316d51773c093e74e15de805e8bf620d6b56bc8bcristy% o exception: return any errors or warnings in this structure. 130316d51773c093e74e15de805e8bf620d6b56bc8bcristy% 131316d51773c093e74e15de805e8bf620d6b56bc8bcristy*/ 132316d51773c093e74e15de805e8bf620d6b56bc8bcristy 13395a072b9674d607b5318a3283fd3952e82107828cristytypedef struct _PixelChannels 134ba18a7a20da567238922ea992832fd3c8f70e7bbcristy{ 135a19f1d70e9a9f88279c4ecafe6dfafc1f9a09599cristy double 1365f95f4f77efc46ff53593d750491c8f60698c983cristy channel[CompositePixelChannel]; 13795a072b9674d607b5318a3283fd3952e82107828cristy} PixelChannels; 138ba18a7a20da567238922ea992832fd3c8f70e7bbcristy 13995a072b9674d607b5318a3283fd3952e82107828cristystatic PixelChannels **DestroyPixelThreadSet(PixelChannels **pixels) 140316d51773c093e74e15de805e8bf620d6b56bc8bcristy{ 141bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy register ssize_t 142316d51773c093e74e15de805e8bf620d6b56bc8bcristy i; 143316d51773c093e74e15de805e8bf620d6b56bc8bcristy 14495a072b9674d607b5318a3283fd3952e82107828cristy assert(pixels != (PixelChannels **) NULL); 145ac245f8a51ea65b085d751c41d8ca4b426bdfe5bcristy for (i=0; i < (ssize_t) GetMagickResourceLimit(ThreadResource); i++) 14695a072b9674d607b5318a3283fd3952e82107828cristy if (pixels[i] != (PixelChannels *) NULL) 14795a072b9674d607b5318a3283fd3952e82107828cristy pixels[i]=(PixelChannels *) RelinquishMagickMemory(pixels[i]); 14895a072b9674d607b5318a3283fd3952e82107828cristy pixels=(PixelChannels **) RelinquishMagickMemory(pixels); 149316d51773c093e74e15de805e8bf620d6b56bc8bcristy return(pixels); 150316d51773c093e74e15de805e8bf620d6b56bc8bcristy} 151316d51773c093e74e15de805e8bf620d6b56bc8bcristy 152751a6671c9b7480f3672a7ef6aa6e392f064b46ddirkstatic PixelChannels **AcquirePixelThreadSet(const Image *image) 153316d51773c093e74e15de805e8bf620d6b56bc8bcristy{ 15495a072b9674d607b5318a3283fd3952e82107828cristy PixelChannels 155316d51773c093e74e15de805e8bf620d6b56bc8bcristy **pixels; 156316d51773c093e74e15de805e8bf620d6b56bc8bcristy 157af1feeee51c32b77405b02abb3e0d655458e2621Cristy register ssize_t 158af1feeee51c32b77405b02abb3e0d655458e2621Cristy i; 159af1feeee51c32b77405b02abb3e0d655458e2621Cristy 160bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy size_t 161316d51773c093e74e15de805e8bf620d6b56bc8bcristy number_threads; 162316d51773c093e74e15de805e8bf620d6b56bc8bcristy 1639357bdd9a30c3d65ef8812e45220f7552dc4376bcristy number_threads=(size_t) GetMagickResourceLimit(ThreadResource); 164e2a912b6c9086c98ec838baa0824cd8deca55538cristy pixels=(PixelChannels **) AcquireQuantumMemory(number_threads, 165e2a912b6c9086c98ec838baa0824cd8deca55538cristy sizeof(*pixels)); 16695a072b9674d607b5318a3283fd3952e82107828cristy if (pixels == (PixelChannels **) NULL) 16795a072b9674d607b5318a3283fd3952e82107828cristy return((PixelChannels **) NULL); 168316d51773c093e74e15de805e8bf620d6b56bc8bcristy (void) ResetMagickMemory(pixels,0,number_threads*sizeof(*pixels)); 169bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy for (i=0; i < (ssize_t) number_threads; i++) 170316d51773c093e74e15de805e8bf620d6b56bc8bcristy { 171ba18a7a20da567238922ea992832fd3c8f70e7bbcristy register ssize_t 172ba18a7a20da567238922ea992832fd3c8f70e7bbcristy j; 173ba18a7a20da567238922ea992832fd3c8f70e7bbcristy 174b21069ba490260839c06334bdce983c4022781b0Cristy pixels[i]=(PixelChannels *) AcquireQuantumMemory(image->columns, 175b21069ba490260839c06334bdce983c4022781b0Cristy sizeof(**pixels)); 17695a072b9674d607b5318a3283fd3952e82107828cristy if (pixels[i] == (PixelChannels *) NULL) 177316d51773c093e74e15de805e8bf620d6b56bc8bcristy return(DestroyPixelThreadSet(pixels)); 178b21069ba490260839c06334bdce983c4022781b0Cristy for (j=0; j < (ssize_t) image->columns; j++) 179ba18a7a20da567238922ea992832fd3c8f70e7bbcristy { 180ba18a7a20da567238922ea992832fd3c8f70e7bbcristy register ssize_t 181ba18a7a20da567238922ea992832fd3c8f70e7bbcristy k; 182ba18a7a20da567238922ea992832fd3c8f70e7bbcristy 183ba18a7a20da567238922ea992832fd3c8f70e7bbcristy for (k=0; k < MaxPixelChannels; k++) 184ba18a7a20da567238922ea992832fd3c8f70e7bbcristy pixels[i][j].channel[k]=0.0; 185ba18a7a20da567238922ea992832fd3c8f70e7bbcristy } 186316d51773c093e74e15de805e8bf620d6b56bc8bcristy } 187316d51773c093e74e15de805e8bf620d6b56bc8bcristy return(pixels); 188316d51773c093e74e15de805e8bf620d6b56bc8bcristy} 189316d51773c093e74e15de805e8bf620d6b56bc8bcristy 190a50f0c85d273f79dee2726d0ad8481423f4bc5f8cristystatic inline double EvaluateMax(const double x,const double y) 191a50f0c85d273f79dee2726d0ad8481423f4bc5f8cristy{ 192a50f0c85d273f79dee2726d0ad8481423f4bc5f8cristy if (x > y) 193a50f0c85d273f79dee2726d0ad8481423f4bc5f8cristy return(x); 194a50f0c85d273f79dee2726d0ad8481423f4bc5f8cristy return(y); 195a50f0c85d273f79dee2726d0ad8481423f4bc5f8cristy} 196a50f0c85d273f79dee2726d0ad8481423f4bc5f8cristy 19708a3d70530ab973a425c8cdce82396825b6a7834cristy#if defined(__cplusplus) || defined(c_plusplus) 19808a3d70530ab973a425c8cdce82396825b6a7834cristyextern "C" { 19908a3d70530ab973a425c8cdce82396825b6a7834cristy#endif 20008a3d70530ab973a425c8cdce82396825b6a7834cristy 20108a3d70530ab973a425c8cdce82396825b6a7834cristystatic int IntensityCompare(const void *x,const void *y) 20208a3d70530ab973a425c8cdce82396825b6a7834cristy{ 20395a072b9674d607b5318a3283fd3952e82107828cristy const PixelChannels 20408a3d70530ab973a425c8cdce82396825b6a7834cristy *color_1, 20508a3d70530ab973a425c8cdce82396825b6a7834cristy *color_2; 20608a3d70530ab973a425c8cdce82396825b6a7834cristy 207a19f1d70e9a9f88279c4ecafe6dfafc1f9a09599cristy double 208ba18a7a20da567238922ea992832fd3c8f70e7bbcristy distance; 209ba18a7a20da567238922ea992832fd3c8f70e7bbcristy 210ba18a7a20da567238922ea992832fd3c8f70e7bbcristy register ssize_t 211ba18a7a20da567238922ea992832fd3c8f70e7bbcristy i; 21208a3d70530ab973a425c8cdce82396825b6a7834cristy 21395a072b9674d607b5318a3283fd3952e82107828cristy color_1=(const PixelChannels *) x; 21495a072b9674d607b5318a3283fd3952e82107828cristy color_2=(const PixelChannels *) y; 215ba18a7a20da567238922ea992832fd3c8f70e7bbcristy distance=0.0; 216ba18a7a20da567238922ea992832fd3c8f70e7bbcristy for (i=0; i < MaxPixelChannels; i++) 217a19f1d70e9a9f88279c4ecafe6dfafc1f9a09599cristy distance+=color_1->channel[i]-(double) color_2->channel[i]; 218ba18a7a20da567238922ea992832fd3c8f70e7bbcristy return(distance < 0 ? -1 : distance > 0 ? 1 : 0); 21908a3d70530ab973a425c8cdce82396825b6a7834cristy} 22008a3d70530ab973a425c8cdce82396825b6a7834cristy 22108a3d70530ab973a425c8cdce82396825b6a7834cristy#if defined(__cplusplus) || defined(c_plusplus) 22208a3d70530ab973a425c8cdce82396825b6a7834cristy} 22308a3d70530ab973a425c8cdce82396825b6a7834cristy#endif 22408a3d70530ab973a425c8cdce82396825b6a7834cristy 22584ff57f38f4ae2f2f52fbbf22a6511635f29c35bcristystatic double ApplyEvaluateOperator(RandomInfo *random_info,const Quantum pixel, 22684ff57f38f4ae2f2f52fbbf22a6511635f29c35bcristy const MagickEvaluateOperator op,const double value) 227351842fbf91597bd44b6200df92c8d45c98fe5adcristy{ 228a19f1d70e9a9f88279c4ecafe6dfafc1f9a09599cristy double 229351842fbf91597bd44b6200df92c8d45c98fe5adcristy result; 230351842fbf91597bd44b6200df92c8d45c98fe5adcristy 231351842fbf91597bd44b6200df92c8d45c98fe5adcristy result=0.0; 232351842fbf91597bd44b6200df92c8d45c98fe5adcristy switch (op) 233351842fbf91597bd44b6200df92c8d45c98fe5adcristy { 234351842fbf91597bd44b6200df92c8d45c98fe5adcristy case UndefinedEvaluateOperator: 235351842fbf91597bd44b6200df92c8d45c98fe5adcristy break; 23633aaed249b7e64a7e43ef086334235f1de342bbccristy case AbsEvaluateOperator: 23733aaed249b7e64a7e43ef086334235f1de342bbccristy { 238a19f1d70e9a9f88279c4ecafe6dfafc1f9a09599cristy result=(double) fabs((double) (pixel+value)); 23933aaed249b7e64a7e43ef086334235f1de342bbccristy break; 24033aaed249b7e64a7e43ef086334235f1de342bbccristy } 241351842fbf91597bd44b6200df92c8d45c98fe5adcristy case AddEvaluateOperator: 242351842fbf91597bd44b6200df92c8d45c98fe5adcristy { 243a19f1d70e9a9f88279c4ecafe6dfafc1f9a09599cristy result=(double) (pixel+value); 244351842fbf91597bd44b6200df92c8d45c98fe5adcristy break; 245351842fbf91597bd44b6200df92c8d45c98fe5adcristy } 246351842fbf91597bd44b6200df92c8d45c98fe5adcristy case AddModulusEvaluateOperator: 247351842fbf91597bd44b6200df92c8d45c98fe5adcristy { 248351842fbf91597bd44b6200df92c8d45c98fe5adcristy /* 249e2a912b6c9086c98ec838baa0824cd8deca55538cristy This returns a 'floored modulus' of the addition which is a positive 250e2a912b6c9086c98ec838baa0824cd8deca55538cristy result. It differs from % or fmod() that returns a 'truncated modulus' 251e2a912b6c9086c98ec838baa0824cd8deca55538cristy result, where floor() is replaced by trunc() and could return a 252e2a912b6c9086c98ec838baa0824cd8deca55538cristy negative result (which is clipped). 253351842fbf91597bd44b6200df92c8d45c98fe5adcristy */ 254351842fbf91597bd44b6200df92c8d45c98fe5adcristy result=pixel+value; 255364a8e2b0fc2f71afc727196466c0a5f54fce738cristy result-=(QuantumRange+1.0)*floor((double) result/(QuantumRange+1.0)); 256351842fbf91597bd44b6200df92c8d45c98fe5adcristy break; 257351842fbf91597bd44b6200df92c8d45c98fe5adcristy } 258351842fbf91597bd44b6200df92c8d45c98fe5adcristy case AndEvaluateOperator: 259351842fbf91597bd44b6200df92c8d45c98fe5adcristy { 260a19f1d70e9a9f88279c4ecafe6dfafc1f9a09599cristy result=(double) ((size_t) pixel & (size_t) (value+0.5)); 261351842fbf91597bd44b6200df92c8d45c98fe5adcristy break; 262351842fbf91597bd44b6200df92c8d45c98fe5adcristy } 263351842fbf91597bd44b6200df92c8d45c98fe5adcristy case CosineEvaluateOperator: 264351842fbf91597bd44b6200df92c8d45c98fe5adcristy { 265a19f1d70e9a9f88279c4ecafe6dfafc1f9a09599cristy result=(double) (QuantumRange*(0.5*cos((double) (2.0*MagickPI* 266351842fbf91597bd44b6200df92c8d45c98fe5adcristy QuantumScale*pixel*value))+0.5)); 267351842fbf91597bd44b6200df92c8d45c98fe5adcristy break; 268351842fbf91597bd44b6200df92c8d45c98fe5adcristy } 269351842fbf91597bd44b6200df92c8d45c98fe5adcristy case DivideEvaluateOperator: 270351842fbf91597bd44b6200df92c8d45c98fe5adcristy { 271351842fbf91597bd44b6200df92c8d45c98fe5adcristy result=pixel/(value == 0.0 ? 1.0 : value); 272351842fbf91597bd44b6200df92c8d45c98fe5adcristy break; 273351842fbf91597bd44b6200df92c8d45c98fe5adcristy } 2749fe8cd76fbf1dc52cef01a2b137ca1b659b244c8cristy case ExponentialEvaluateOperator: 2759fe8cd76fbf1dc52cef01a2b137ca1b659b244c8cristy { 27684ff57f38f4ae2f2f52fbbf22a6511635f29c35bcristy result=(double) (QuantumRange*exp((double) (value*QuantumScale*pixel))); 2779fe8cd76fbf1dc52cef01a2b137ca1b659b244c8cristy break; 2789fe8cd76fbf1dc52cef01a2b137ca1b659b244c8cristy } 279351842fbf91597bd44b6200df92c8d45c98fe5adcristy case GaussianNoiseEvaluateOperator: 280351842fbf91597bd44b6200df92c8d45c98fe5adcristy { 281a19f1d70e9a9f88279c4ecafe6dfafc1f9a09599cristy result=(double) GenerateDifferentialNoise(random_info,pixel, 282351842fbf91597bd44b6200df92c8d45c98fe5adcristy GaussianNoise,value); 283351842fbf91597bd44b6200df92c8d45c98fe5adcristy break; 284351842fbf91597bd44b6200df92c8d45c98fe5adcristy } 285351842fbf91597bd44b6200df92c8d45c98fe5adcristy case ImpulseNoiseEvaluateOperator: 286351842fbf91597bd44b6200df92c8d45c98fe5adcristy { 28784ff57f38f4ae2f2f52fbbf22a6511635f29c35bcristy result=(double) GenerateDifferentialNoise(random_info,pixel,ImpulseNoise, 28884ff57f38f4ae2f2f52fbbf22a6511635f29c35bcristy value); 289351842fbf91597bd44b6200df92c8d45c98fe5adcristy break; 290351842fbf91597bd44b6200df92c8d45c98fe5adcristy } 291351842fbf91597bd44b6200df92c8d45c98fe5adcristy case LaplacianNoiseEvaluateOperator: 292351842fbf91597bd44b6200df92c8d45c98fe5adcristy { 293a19f1d70e9a9f88279c4ecafe6dfafc1f9a09599cristy result=(double) GenerateDifferentialNoise(random_info,pixel, 294351842fbf91597bd44b6200df92c8d45c98fe5adcristy LaplacianNoise,value); 295351842fbf91597bd44b6200df92c8d45c98fe5adcristy break; 296351842fbf91597bd44b6200df92c8d45c98fe5adcristy } 297351842fbf91597bd44b6200df92c8d45c98fe5adcristy case LeftShiftEvaluateOperator: 298351842fbf91597bd44b6200df92c8d45c98fe5adcristy { 299a19f1d70e9a9f88279c4ecafe6dfafc1f9a09599cristy result=(double) ((size_t) pixel << (size_t) (value+0.5)); 300351842fbf91597bd44b6200df92c8d45c98fe5adcristy break; 301351842fbf91597bd44b6200df92c8d45c98fe5adcristy } 302351842fbf91597bd44b6200df92c8d45c98fe5adcristy case LogEvaluateOperator: 303351842fbf91597bd44b6200df92c8d45c98fe5adcristy { 304a9b9d2efa02426f73a9ecad1bf1e4401d5a6d852cristy if ((QuantumScale*pixel) >= MagickEpsilon) 30584ff57f38f4ae2f2f52fbbf22a6511635f29c35bcristy result=(double) (QuantumRange*log((double) (QuantumScale*value*pixel+ 30684ff57f38f4ae2f2f52fbbf22a6511635f29c35bcristy 1.0))/log((double) (value+1.0))); 307351842fbf91597bd44b6200df92c8d45c98fe5adcristy break; 308351842fbf91597bd44b6200df92c8d45c98fe5adcristy } 309351842fbf91597bd44b6200df92c8d45c98fe5adcristy case MaxEvaluateOperator: 310351842fbf91597bd44b6200df92c8d45c98fe5adcristy { 311a50f0c85d273f79dee2726d0ad8481423f4bc5f8cristy result=(double) EvaluateMax((double) pixel,value); 312351842fbf91597bd44b6200df92c8d45c98fe5adcristy break; 313351842fbf91597bd44b6200df92c8d45c98fe5adcristy } 314351842fbf91597bd44b6200df92c8d45c98fe5adcristy case MeanEvaluateOperator: 315351842fbf91597bd44b6200df92c8d45c98fe5adcristy { 316a19f1d70e9a9f88279c4ecafe6dfafc1f9a09599cristy result=(double) (pixel+value); 317351842fbf91597bd44b6200df92c8d45c98fe5adcristy break; 318351842fbf91597bd44b6200df92c8d45c98fe5adcristy } 31908a3d70530ab973a425c8cdce82396825b6a7834cristy case MedianEvaluateOperator: 32008a3d70530ab973a425c8cdce82396825b6a7834cristy { 321a19f1d70e9a9f88279c4ecafe6dfafc1f9a09599cristy result=(double) (pixel+value); 32208a3d70530ab973a425c8cdce82396825b6a7834cristy break; 32308a3d70530ab973a425c8cdce82396825b6a7834cristy } 324351842fbf91597bd44b6200df92c8d45c98fe5adcristy case MinEvaluateOperator: 325351842fbf91597bd44b6200df92c8d45c98fe5adcristy { 326a50f0c85d273f79dee2726d0ad8481423f4bc5f8cristy result=(double) MagickMin((double) pixel,value); 327351842fbf91597bd44b6200df92c8d45c98fe5adcristy break; 328351842fbf91597bd44b6200df92c8d45c98fe5adcristy } 329351842fbf91597bd44b6200df92c8d45c98fe5adcristy case MultiplicativeNoiseEvaluateOperator: 330351842fbf91597bd44b6200df92c8d45c98fe5adcristy { 331a19f1d70e9a9f88279c4ecafe6dfafc1f9a09599cristy result=(double) GenerateDifferentialNoise(random_info,pixel, 332351842fbf91597bd44b6200df92c8d45c98fe5adcristy MultiplicativeGaussianNoise,value); 333351842fbf91597bd44b6200df92c8d45c98fe5adcristy break; 334351842fbf91597bd44b6200df92c8d45c98fe5adcristy } 335351842fbf91597bd44b6200df92c8d45c98fe5adcristy case MultiplyEvaluateOperator: 336351842fbf91597bd44b6200df92c8d45c98fe5adcristy { 337a19f1d70e9a9f88279c4ecafe6dfafc1f9a09599cristy result=(double) (value*pixel); 338351842fbf91597bd44b6200df92c8d45c98fe5adcristy break; 339351842fbf91597bd44b6200df92c8d45c98fe5adcristy } 340351842fbf91597bd44b6200df92c8d45c98fe5adcristy case OrEvaluateOperator: 341351842fbf91597bd44b6200df92c8d45c98fe5adcristy { 342a19f1d70e9a9f88279c4ecafe6dfafc1f9a09599cristy result=(double) ((size_t) pixel | (size_t) (value+0.5)); 343351842fbf91597bd44b6200df92c8d45c98fe5adcristy break; 344351842fbf91597bd44b6200df92c8d45c98fe5adcristy } 345351842fbf91597bd44b6200df92c8d45c98fe5adcristy case PoissonNoiseEvaluateOperator: 346351842fbf91597bd44b6200df92c8d45c98fe5adcristy { 34784ff57f38f4ae2f2f52fbbf22a6511635f29c35bcristy result=(double) GenerateDifferentialNoise(random_info,pixel,PoissonNoise, 34884ff57f38f4ae2f2f52fbbf22a6511635f29c35bcristy value); 349351842fbf91597bd44b6200df92c8d45c98fe5adcristy break; 350351842fbf91597bd44b6200df92c8d45c98fe5adcristy } 351351842fbf91597bd44b6200df92c8d45c98fe5adcristy case PowEvaluateOperator: 352351842fbf91597bd44b6200df92c8d45c98fe5adcristy { 35384ff57f38f4ae2f2f52fbbf22a6511635f29c35bcristy result=(double) (QuantumRange*pow((double) (QuantumScale*pixel),(double) 35484ff57f38f4ae2f2f52fbbf22a6511635f29c35bcristy value)); 355351842fbf91597bd44b6200df92c8d45c98fe5adcristy break; 356351842fbf91597bd44b6200df92c8d45c98fe5adcristy } 357351842fbf91597bd44b6200df92c8d45c98fe5adcristy case RightShiftEvaluateOperator: 358351842fbf91597bd44b6200df92c8d45c98fe5adcristy { 359a19f1d70e9a9f88279c4ecafe6dfafc1f9a09599cristy result=(double) ((size_t) pixel >> (size_t) (value+0.5)); 360351842fbf91597bd44b6200df92c8d45c98fe5adcristy break; 361351842fbf91597bd44b6200df92c8d45c98fe5adcristy } 3627c4c78fe1a6a4884ad06dcf886cd1f6a40cc037ccristy case RootMeanSquareEvaluateOperator: 3637c4c78fe1a6a4884ad06dcf886cd1f6a40cc037ccristy { 3647c4c78fe1a6a4884ad06dcf886cd1f6a40cc037ccristy result=(double) (pixel*pixel+value); 3657c4c78fe1a6a4884ad06dcf886cd1f6a40cc037ccristy break; 3667c4c78fe1a6a4884ad06dcf886cd1f6a40cc037ccristy } 367351842fbf91597bd44b6200df92c8d45c98fe5adcristy case SetEvaluateOperator: 368351842fbf91597bd44b6200df92c8d45c98fe5adcristy { 369351842fbf91597bd44b6200df92c8d45c98fe5adcristy result=value; 370351842fbf91597bd44b6200df92c8d45c98fe5adcristy break; 371351842fbf91597bd44b6200df92c8d45c98fe5adcristy } 372351842fbf91597bd44b6200df92c8d45c98fe5adcristy case SineEvaluateOperator: 373351842fbf91597bd44b6200df92c8d45c98fe5adcristy { 374a19f1d70e9a9f88279c4ecafe6dfafc1f9a09599cristy result=(double) (QuantumRange*(0.5*sin((double) (2.0*MagickPI* 375351842fbf91597bd44b6200df92c8d45c98fe5adcristy QuantumScale*pixel*value))+0.5)); 376351842fbf91597bd44b6200df92c8d45c98fe5adcristy break; 377351842fbf91597bd44b6200df92c8d45c98fe5adcristy } 378351842fbf91597bd44b6200df92c8d45c98fe5adcristy case SubtractEvaluateOperator: 379351842fbf91597bd44b6200df92c8d45c98fe5adcristy { 380a19f1d70e9a9f88279c4ecafe6dfafc1f9a09599cristy result=(double) (pixel-value); 381351842fbf91597bd44b6200df92c8d45c98fe5adcristy break; 382351842fbf91597bd44b6200df92c8d45c98fe5adcristy } 38312a3f8e5d02c1f840a79232564641eee7e0aea6dcristy case SumEvaluateOperator: 38412a3f8e5d02c1f840a79232564641eee7e0aea6dcristy { 385a19f1d70e9a9f88279c4ecafe6dfafc1f9a09599cristy result=(double) (pixel+value); 38612a3f8e5d02c1f840a79232564641eee7e0aea6dcristy break; 38712a3f8e5d02c1f840a79232564641eee7e0aea6dcristy } 388351842fbf91597bd44b6200df92c8d45c98fe5adcristy case ThresholdEvaluateOperator: 389351842fbf91597bd44b6200df92c8d45c98fe5adcristy { 39084ff57f38f4ae2f2f52fbbf22a6511635f29c35bcristy result=(double) (((double) pixel <= value) ? 0 : QuantumRange); 391351842fbf91597bd44b6200df92c8d45c98fe5adcristy break; 392351842fbf91597bd44b6200df92c8d45c98fe5adcristy } 393351842fbf91597bd44b6200df92c8d45c98fe5adcristy case ThresholdBlackEvaluateOperator: 394351842fbf91597bd44b6200df92c8d45c98fe5adcristy { 395a19f1d70e9a9f88279c4ecafe6dfafc1f9a09599cristy result=(double) (((double) pixel <= value) ? 0 : pixel); 396351842fbf91597bd44b6200df92c8d45c98fe5adcristy break; 397351842fbf91597bd44b6200df92c8d45c98fe5adcristy } 398351842fbf91597bd44b6200df92c8d45c98fe5adcristy case ThresholdWhiteEvaluateOperator: 399351842fbf91597bd44b6200df92c8d45c98fe5adcristy { 40084ff57f38f4ae2f2f52fbbf22a6511635f29c35bcristy result=(double) (((double) pixel > value) ? QuantumRange : pixel); 401351842fbf91597bd44b6200df92c8d45c98fe5adcristy break; 402351842fbf91597bd44b6200df92c8d45c98fe5adcristy } 403351842fbf91597bd44b6200df92c8d45c98fe5adcristy case UniformNoiseEvaluateOperator: 404351842fbf91597bd44b6200df92c8d45c98fe5adcristy { 40584ff57f38f4ae2f2f52fbbf22a6511635f29c35bcristy result=(double) GenerateDifferentialNoise(random_info,pixel,UniformNoise, 40684ff57f38f4ae2f2f52fbbf22a6511635f29c35bcristy value); 407351842fbf91597bd44b6200df92c8d45c98fe5adcristy break; 408351842fbf91597bd44b6200df92c8d45c98fe5adcristy } 409351842fbf91597bd44b6200df92c8d45c98fe5adcristy case XorEvaluateOperator: 410351842fbf91597bd44b6200df92c8d45c98fe5adcristy { 411a19f1d70e9a9f88279c4ecafe6dfafc1f9a09599cristy result=(double) ((size_t) pixel ^ (size_t) (value+0.5)); 412351842fbf91597bd44b6200df92c8d45c98fe5adcristy break; 413351842fbf91597bd44b6200df92c8d45c98fe5adcristy } 414351842fbf91597bd44b6200df92c8d45c98fe5adcristy } 415d18ae7ce9b6ff934472abb8e3fa73d0c1aed7d20cristy return(result); 416351842fbf91597bd44b6200df92c8d45c98fe5adcristy} 417351842fbf91597bd44b6200df92c8d45c98fe5adcristy 418d18ae7ce9b6ff934472abb8e3fa73d0c1aed7d20cristyMagickExport Image *EvaluateImages(const Image *images, 419d18ae7ce9b6ff934472abb8e3fa73d0c1aed7d20cristy const MagickEvaluateOperator op,ExceptionInfo *exception) 420d18ae7ce9b6ff934472abb8e3fa73d0c1aed7d20cristy{ 421d18ae7ce9b6ff934472abb8e3fa73d0c1aed7d20cristy#define EvaluateImageTag "Evaluate/Image" 422d18ae7ce9b6ff934472abb8e3fa73d0c1aed7d20cristy 423d18ae7ce9b6ff934472abb8e3fa73d0c1aed7d20cristy CacheView 424d18ae7ce9b6ff934472abb8e3fa73d0c1aed7d20cristy *evaluate_view; 425d18ae7ce9b6ff934472abb8e3fa73d0c1aed7d20cristy 426d18ae7ce9b6ff934472abb8e3fa73d0c1aed7d20cristy Image 4274ee2b0c11849aca22cbc22f1fb48e3ee9c8eaba5cristy *image; 428d18ae7ce9b6ff934472abb8e3fa73d0c1aed7d20cristy 429d18ae7ce9b6ff934472abb8e3fa73d0c1aed7d20cristy MagickBooleanType 430d18ae7ce9b6ff934472abb8e3fa73d0c1aed7d20cristy status; 431d18ae7ce9b6ff934472abb8e3fa73d0c1aed7d20cristy 4325f959473f334e196c6bf39b740c12cb4963fceebcristy MagickOffsetType 4335f959473f334e196c6bf39b740c12cb4963fceebcristy progress; 4345f959473f334e196c6bf39b740c12cb4963fceebcristy 43595a072b9674d607b5318a3283fd3952e82107828cristy PixelChannels 43605d2ff7ebf21f659f5b11e45afb294e152f4330cdirk **magick_restrict evaluate_pixels; 437d18ae7ce9b6ff934472abb8e3fa73d0c1aed7d20cristy 438d18ae7ce9b6ff934472abb8e3fa73d0c1aed7d20cristy RandomInfo 43905d2ff7ebf21f659f5b11e45afb294e152f4330cdirk **magick_restrict random_info; 440d18ae7ce9b6ff934472abb8e3fa73d0c1aed7d20cristy 441bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy size_t 442d18ae7ce9b6ff934472abb8e3fa73d0c1aed7d20cristy number_images; 443d18ae7ce9b6ff934472abb8e3fa73d0c1aed7d20cristy 4445f959473f334e196c6bf39b740c12cb4963fceebcristy ssize_t 4455f959473f334e196c6bf39b740c12cb4963fceebcristy y; 4465f959473f334e196c6bf39b740c12cb4963fceebcristy 447b36143ff2559783289b92a25d4b4579a6a8b5618glennrp#if defined(MAGICKCORE_OPENMP_SUPPORT) 44857340e008c81f05c0adb4d8874dda11104d8bb7ecristy unsigned long 44957340e008c81f05c0adb4d8874dda11104d8bb7ecristy key; 450b36143ff2559783289b92a25d4b4579a6a8b5618glennrp#endif 45157340e008c81f05c0adb4d8874dda11104d8bb7ecristy 452d18ae7ce9b6ff934472abb8e3fa73d0c1aed7d20cristy assert(images != (Image *) NULL); 453e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy assert(images->signature == MagickCoreSignature); 454d18ae7ce9b6ff934472abb8e3fa73d0c1aed7d20cristy if (images->debug != MagickFalse) 455d18ae7ce9b6ff934472abb8e3fa73d0c1aed7d20cristy (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",images->filename); 456d18ae7ce9b6ff934472abb8e3fa73d0c1aed7d20cristy assert(exception != (ExceptionInfo *) NULL); 457e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy assert(exception->signature == MagickCoreSignature); 4584ee2b0c11849aca22cbc22f1fb48e3ee9c8eaba5cristy image=CloneImage(images,images->columns,images->rows,MagickTrue, 459d18ae7ce9b6ff934472abb8e3fa73d0c1aed7d20cristy exception); 4604ee2b0c11849aca22cbc22f1fb48e3ee9c8eaba5cristy if (image == (Image *) NULL) 461d18ae7ce9b6ff934472abb8e3fa73d0c1aed7d20cristy return((Image *) NULL); 4624ee2b0c11849aca22cbc22f1fb48e3ee9c8eaba5cristy if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse) 463d18ae7ce9b6ff934472abb8e3fa73d0c1aed7d20cristy { 4644ee2b0c11849aca22cbc22f1fb48e3ee9c8eaba5cristy image=DestroyImage(image); 465d18ae7ce9b6ff934472abb8e3fa73d0c1aed7d20cristy return((Image *) NULL); 466d18ae7ce9b6ff934472abb8e3fa73d0c1aed7d20cristy } 46708a3d70530ab973a425c8cdce82396825b6a7834cristy number_images=GetImageListLength(images); 468751a6671c9b7480f3672a7ef6aa6e392f064b46ddirk evaluate_pixels=AcquirePixelThreadSet(images); 46995a072b9674d607b5318a3283fd3952e82107828cristy if (evaluate_pixels == (PixelChannels **) NULL) 470d18ae7ce9b6ff934472abb8e3fa73d0c1aed7d20cristy { 4714ee2b0c11849aca22cbc22f1fb48e3ee9c8eaba5cristy image=DestroyImage(image); 472d18ae7ce9b6ff934472abb8e3fa73d0c1aed7d20cristy (void) ThrowMagickException(exception,GetMagickModule(), 473efe601ce9ea5ad34ad0e8ad6e61d9be9b148b2a3cristy ResourceLimitError,"MemoryAllocationFailed","`%s'",images->filename); 474d18ae7ce9b6ff934472abb8e3fa73d0c1aed7d20cristy return((Image *) NULL); 475d18ae7ce9b6ff934472abb8e3fa73d0c1aed7d20cristy } 476d18ae7ce9b6ff934472abb8e3fa73d0c1aed7d20cristy /* 477d18ae7ce9b6ff934472abb8e3fa73d0c1aed7d20cristy Evaluate image pixels. 478d18ae7ce9b6ff934472abb8e3fa73d0c1aed7d20cristy */ 479d18ae7ce9b6ff934472abb8e3fa73d0c1aed7d20cristy status=MagickTrue; 480d18ae7ce9b6ff934472abb8e3fa73d0c1aed7d20cristy progress=0; 481d18ae7ce9b6ff934472abb8e3fa73d0c1aed7d20cristy random_info=AcquireRandomInfoThreadSet(); 48246ff2676b1044ea4101ac7a59b83289cd8f6cfdacristy evaluate_view=AcquireAuthenticCacheView(image,exception); 48308a3d70530ab973a425c8cdce82396825b6a7834cristy if (op == MedianEvaluateOperator) 48408a3d70530ab973a425c8cdce82396825b6a7834cristy { 485e2a912b6c9086c98ec838baa0824cd8deca55538cristy#if defined(MAGICKCORE_OPENMP_SUPPORT) 486ecd6dd161dfefd2b14a11c3d907bdeb648f5e201cristy key=GetRandomSecretKey(random_info[0]); 4879a5a52fdbea9190e1c868ba9298a6f64d1c896d1cristy #pragma omp parallel for schedule(static,4) shared(progress,status) \ 4885e6b259130f9dbe0da4666f734937017babe573acristy magick_threads(image,images,image->rows,key == ~0UL) 489a30fec6bcaca00206491523e7b7b59e707f15339cristy#endif 4904ee2b0c11849aca22cbc22f1fb48e3ee9c8eaba5cristy for (y=0; y < (ssize_t) image->rows; y++) 491a30fec6bcaca00206491523e7b7b59e707f15339cristy { 492a30fec6bcaca00206491523e7b7b59e707f15339cristy CacheView 493a30fec6bcaca00206491523e7b7b59e707f15339cristy *image_view; 494d18ae7ce9b6ff934472abb8e3fa73d0c1aed7d20cristy 495a30fec6bcaca00206491523e7b7b59e707f15339cristy const Image 496a30fec6bcaca00206491523e7b7b59e707f15339cristy *next; 497d18ae7ce9b6ff934472abb8e3fa73d0c1aed7d20cristy 498a30fec6bcaca00206491523e7b7b59e707f15339cristy const int 499a30fec6bcaca00206491523e7b7b59e707f15339cristy id = GetOpenMPThreadId(); 5006ebe97c3470475a87f649cfab09fa0cf1f249da3cristy 501a30fec6bcaca00206491523e7b7b59e707f15339cristy register PixelChannels 502a30fec6bcaca00206491523e7b7b59e707f15339cristy *evaluate_pixel; 503d18ae7ce9b6ff934472abb8e3fa73d0c1aed7d20cristy 504a30fec6bcaca00206491523e7b7b59e707f15339cristy register Quantum 50505d2ff7ebf21f659f5b11e45afb294e152f4330cdirk *magick_restrict q; 506d18ae7ce9b6ff934472abb8e3fa73d0c1aed7d20cristy 507a30fec6bcaca00206491523e7b7b59e707f15339cristy register ssize_t 508a30fec6bcaca00206491523e7b7b59e707f15339cristy x; 509d18ae7ce9b6ff934472abb8e3fa73d0c1aed7d20cristy 510a30fec6bcaca00206491523e7b7b59e707f15339cristy if (status == MagickFalse) 51108a3d70530ab973a425c8cdce82396825b6a7834cristy continue; 51214a436ee80433ecd346653ee3ca478d3dbe7edf2cristy q=QueueCacheViewAuthenticPixels(evaluate_view,0,y,image->columns,1, 51314a436ee80433ecd346653ee3ca478d3dbe7edf2cristy exception); 514a30fec6bcaca00206491523e7b7b59e707f15339cristy if (q == (Quantum *) NULL) 515a30fec6bcaca00206491523e7b7b59e707f15339cristy { 516a30fec6bcaca00206491523e7b7b59e707f15339cristy status=MagickFalse; 517a30fec6bcaca00206491523e7b7b59e707f15339cristy continue; 518a30fec6bcaca00206491523e7b7b59e707f15339cristy } 519a30fec6bcaca00206491523e7b7b59e707f15339cristy evaluate_pixel=evaluate_pixels[id]; 5204ee2b0c11849aca22cbc22f1fb48e3ee9c8eaba5cristy for (x=0; x < (ssize_t) image->columns; x++) 521a30fec6bcaca00206491523e7b7b59e707f15339cristy { 522a30fec6bcaca00206491523e7b7b59e707f15339cristy register ssize_t 523a30fec6bcaca00206491523e7b7b59e707f15339cristy j, 524a30fec6bcaca00206491523e7b7b59e707f15339cristy k; 525a30fec6bcaca00206491523e7b7b59e707f15339cristy 526a30fec6bcaca00206491523e7b7b59e707f15339cristy for (j=0; j < (ssize_t) number_images; j++) 527a30fec6bcaca00206491523e7b7b59e707f15339cristy for (k=0; k < MaxPixelChannels; k++) 528a30fec6bcaca00206491523e7b7b59e707f15339cristy evaluate_pixel[j].channel[k]=0.0; 529a30fec6bcaca00206491523e7b7b59e707f15339cristy next=images; 530a30fec6bcaca00206491523e7b7b59e707f15339cristy for (j=0; j < (ssize_t) number_images; j++) 531a30fec6bcaca00206491523e7b7b59e707f15339cristy { 532a30fec6bcaca00206491523e7b7b59e707f15339cristy register const Quantum 533a30fec6bcaca00206491523e7b7b59e707f15339cristy *p; 534a30fec6bcaca00206491523e7b7b59e707f15339cristy 535a30fec6bcaca00206491523e7b7b59e707f15339cristy register ssize_t 536a30fec6bcaca00206491523e7b7b59e707f15339cristy i; 537a30fec6bcaca00206491523e7b7b59e707f15339cristy 53846ff2676b1044ea4101ac7a59b83289cd8f6cfdacristy image_view=AcquireVirtualCacheView(next,exception); 539a30fec6bcaca00206491523e7b7b59e707f15339cristy p=GetCacheViewVirtualPixels(image_view,x,y,1,1,exception); 540a30fec6bcaca00206491523e7b7b59e707f15339cristy if (p == (const Quantum *) NULL) 541a30fec6bcaca00206491523e7b7b59e707f15339cristy { 542a30fec6bcaca00206491523e7b7b59e707f15339cristy image_view=DestroyCacheView(image_view); 543a30fec6bcaca00206491523e7b7b59e707f15339cristy break; 544a30fec6bcaca00206491523e7b7b59e707f15339cristy } 5454ee2b0c11849aca22cbc22f1fb48e3ee9c8eaba5cristy for (i=0; i < (ssize_t) GetPixelChannels(image); i++) 546a30fec6bcaca00206491523e7b7b59e707f15339cristy { 5475a23c55ddcfdf6ae717dd42d8a1c1a2ff8c6305fcristy PixelChannel channel=GetPixelChannelChannel(image,i); 5485a23c55ddcfdf6ae717dd42d8a1c1a2ff8c6305fcristy PixelTrait evaluate_traits=GetPixelChannelTraits(image,channel); 5495a23c55ddcfdf6ae717dd42d8a1c1a2ff8c6305fcristy PixelTrait traits=GetPixelChannelTraits(next,channel); 550a30fec6bcaca00206491523e7b7b59e707f15339cristy if ((traits == UndefinedPixelTrait) || 551a30fec6bcaca00206491523e7b7b59e707f15339cristy (evaluate_traits == UndefinedPixelTrait)) 552a30fec6bcaca00206491523e7b7b59e707f15339cristy continue; 553a30fec6bcaca00206491523e7b7b59e707f15339cristy if ((evaluate_traits & UpdatePixelTrait) == 0) 554a30fec6bcaca00206491523e7b7b59e707f15339cristy continue; 555a30fec6bcaca00206491523e7b7b59e707f15339cristy evaluate_pixel[j].channel[i]=ApplyEvaluateOperator( 5564ee2b0c11849aca22cbc22f1fb48e3ee9c8eaba5cristy random_info[id],GetPixelChannel(image,channel,p),op, 557a30fec6bcaca00206491523e7b7b59e707f15339cristy evaluate_pixel[j].channel[i]); 558a30fec6bcaca00206491523e7b7b59e707f15339cristy } 559a30fec6bcaca00206491523e7b7b59e707f15339cristy image_view=DestroyCacheView(image_view); 560a30fec6bcaca00206491523e7b7b59e707f15339cristy next=GetNextImageInList(next); 561a30fec6bcaca00206491523e7b7b59e707f15339cristy } 562a30fec6bcaca00206491523e7b7b59e707f15339cristy qsort((void *) evaluate_pixel,number_images,sizeof(*evaluate_pixel), 563a30fec6bcaca00206491523e7b7b59e707f15339cristy IntensityCompare); 5644ee2b0c11849aca22cbc22f1fb48e3ee9c8eaba5cristy for (k=0; k < (ssize_t) GetPixelChannels(image); k++) 565a30fec6bcaca00206491523e7b7b59e707f15339cristy q[k]=ClampToQuantum(evaluate_pixel[j/2].channel[k]); 5664ee2b0c11849aca22cbc22f1fb48e3ee9c8eaba5cristy q+=GetPixelChannels(image); 567d18ae7ce9b6ff934472abb8e3fa73d0c1aed7d20cristy } 568a30fec6bcaca00206491523e7b7b59e707f15339cristy if (SyncCacheViewAuthenticPixels(evaluate_view,exception) == MagickFalse) 569a30fec6bcaca00206491523e7b7b59e707f15339cristy status=MagickFalse; 570a30fec6bcaca00206491523e7b7b59e707f15339cristy if (images->progress_monitor != (MagickProgressMonitor) NULL) 571a30fec6bcaca00206491523e7b7b59e707f15339cristy { 572a30fec6bcaca00206491523e7b7b59e707f15339cristy MagickBooleanType 573a30fec6bcaca00206491523e7b7b59e707f15339cristy proceed; 574a30fec6bcaca00206491523e7b7b59e707f15339cristy 575a30fec6bcaca00206491523e7b7b59e707f15339cristy#if defined(MAGICKCORE_OPENMP_SUPPORT) 576a30fec6bcaca00206491523e7b7b59e707f15339cristy #pragma omp critical (MagickCore_EvaluateImages) 577a30fec6bcaca00206491523e7b7b59e707f15339cristy#endif 578a30fec6bcaca00206491523e7b7b59e707f15339cristy proceed=SetImageProgress(images,EvaluateImageTag,progress++, 5794ee2b0c11849aca22cbc22f1fb48e3ee9c8eaba5cristy image->rows); 580a30fec6bcaca00206491523e7b7b59e707f15339cristy if (proceed == MagickFalse) 581a30fec6bcaca00206491523e7b7b59e707f15339cristy status=MagickFalse; 582a30fec6bcaca00206491523e7b7b59e707f15339cristy } 583a30fec6bcaca00206491523e7b7b59e707f15339cristy } 584a30fec6bcaca00206491523e7b7b59e707f15339cristy } 585a30fec6bcaca00206491523e7b7b59e707f15339cristy else 586a30fec6bcaca00206491523e7b7b59e707f15339cristy { 587a30fec6bcaca00206491523e7b7b59e707f15339cristy#if defined(MAGICKCORE_OPENMP_SUPPORT) 588ecd6dd161dfefd2b14a11c3d907bdeb648f5e201cristy key=GetRandomSecretKey(random_info[0]); 5899a5a52fdbea9190e1c868ba9298a6f64d1c896d1cristy #pragma omp parallel for schedule(static,4) shared(progress,status) \ 5905e6b259130f9dbe0da4666f734937017babe573acristy magick_threads(image,images,image->rows,key == ~0UL) 591a30fec6bcaca00206491523e7b7b59e707f15339cristy#endif 5924ee2b0c11849aca22cbc22f1fb48e3ee9c8eaba5cristy for (y=0; y < (ssize_t) image->rows; y++) 593d18ae7ce9b6ff934472abb8e3fa73d0c1aed7d20cristy { 594a30fec6bcaca00206491523e7b7b59e707f15339cristy CacheView 595a30fec6bcaca00206491523e7b7b59e707f15339cristy *image_view; 596a30fec6bcaca00206491523e7b7b59e707f15339cristy 597a30fec6bcaca00206491523e7b7b59e707f15339cristy const Image 598a30fec6bcaca00206491523e7b7b59e707f15339cristy *next; 599a30fec6bcaca00206491523e7b7b59e707f15339cristy 600a30fec6bcaca00206491523e7b7b59e707f15339cristy const int 601a30fec6bcaca00206491523e7b7b59e707f15339cristy id = GetOpenMPThreadId(); 602a30fec6bcaca00206491523e7b7b59e707f15339cristy 60308a3d70530ab973a425c8cdce82396825b6a7834cristy register ssize_t 604a30fec6bcaca00206491523e7b7b59e707f15339cristy i, 605a30fec6bcaca00206491523e7b7b59e707f15339cristy x; 60608a3d70530ab973a425c8cdce82396825b6a7834cristy 607a30fec6bcaca00206491523e7b7b59e707f15339cristy register PixelChannels 608a30fec6bcaca00206491523e7b7b59e707f15339cristy *evaluate_pixel; 609a30fec6bcaca00206491523e7b7b59e707f15339cristy 610a30fec6bcaca00206491523e7b7b59e707f15339cristy register Quantum 61105d2ff7ebf21f659f5b11e45afb294e152f4330cdirk *magick_restrict q; 612a30fec6bcaca00206491523e7b7b59e707f15339cristy 613a30fec6bcaca00206491523e7b7b59e707f15339cristy ssize_t 614a30fec6bcaca00206491523e7b7b59e707f15339cristy j; 615a30fec6bcaca00206491523e7b7b59e707f15339cristy 616a30fec6bcaca00206491523e7b7b59e707f15339cristy if (status == MagickFalse) 617a30fec6bcaca00206491523e7b7b59e707f15339cristy continue; 618edb3f510ac6109703f134e42f9a2a0cc21866d78cristy q=QueueCacheViewAuthenticPixels(evaluate_view,0,y,image->columns,1, 619edb3f510ac6109703f134e42f9a2a0cc21866d78cristy exception); 620a30fec6bcaca00206491523e7b7b59e707f15339cristy if (q == (Quantum *) NULL) 621a30fec6bcaca00206491523e7b7b59e707f15339cristy { 622a30fec6bcaca00206491523e7b7b59e707f15339cristy status=MagickFalse; 623a30fec6bcaca00206491523e7b7b59e707f15339cristy continue; 624a30fec6bcaca00206491523e7b7b59e707f15339cristy } 625a30fec6bcaca00206491523e7b7b59e707f15339cristy evaluate_pixel=evaluate_pixels[id]; 6264ee2b0c11849aca22cbc22f1fb48e3ee9c8eaba5cristy for (j=0; j < (ssize_t) image->columns; j++) 627a30fec6bcaca00206491523e7b7b59e707f15339cristy for (i=0; i < MaxPixelChannels; i++) 628a30fec6bcaca00206491523e7b7b59e707f15339cristy evaluate_pixel[j].channel[i]=0.0; 62908a3d70530ab973a425c8cdce82396825b6a7834cristy next=images; 630ba18a7a20da567238922ea992832fd3c8f70e7bbcristy for (j=0; j < (ssize_t) number_images; j++) 63108a3d70530ab973a425c8cdce82396825b6a7834cristy { 6324c08aed51c5899665ade97263692328eea4af106cristy register const Quantum 63308a3d70530ab973a425c8cdce82396825b6a7834cristy *p; 63408a3d70530ab973a425c8cdce82396825b6a7834cristy 63546ff2676b1044ea4101ac7a59b83289cd8f6cfdacristy image_view=AcquireVirtualCacheView(next,exception); 636b21069ba490260839c06334bdce983c4022781b0Cristy p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1, 637b21069ba490260839c06334bdce983c4022781b0Cristy exception); 6384c08aed51c5899665ade97263692328eea4af106cristy if (p == (const Quantum *) NULL) 63908a3d70530ab973a425c8cdce82396825b6a7834cristy { 64008a3d70530ab973a425c8cdce82396825b6a7834cristy image_view=DestroyCacheView(image_view); 64108a3d70530ab973a425c8cdce82396825b6a7834cristy break; 64208a3d70530ab973a425c8cdce82396825b6a7834cristy } 643b21069ba490260839c06334bdce983c4022781b0Cristy for (x=0; x < (ssize_t) image->columns; x++) 644ba18a7a20da567238922ea992832fd3c8f70e7bbcristy { 645a30fec6bcaca00206491523e7b7b59e707f15339cristy register ssize_t 646a30fec6bcaca00206491523e7b7b59e707f15339cristy i; 647ba18a7a20da567238922ea992832fd3c8f70e7bbcristy 648883fde11debec15cedb05dc5d7228d8588066bc0cristy if (GetPixelReadMask(next,p) == 0) 64910a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy { 650c94ba6f2e80cce201ffaf24ce7534019b6353dfecristy p+=GetPixelChannels(next); 65110a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy continue; 65210a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy } 65310a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy for (i=0; i < (ssize_t) GetPixelChannels(next); i++) 654a30fec6bcaca00206491523e7b7b59e707f15339cristy { 6555a23c55ddcfdf6ae717dd42d8a1c1a2ff8c6305fcristy PixelChannel channel=GetPixelChannelChannel(image,i); 656b21069ba490260839c06334bdce983c4022781b0Cristy PixelTrait traits=GetPixelChannelTraits(next,channel); 657b21069ba490260839c06334bdce983c4022781b0Cristy PixelTrait evaluate_traits=GetPixelChannelTraits(image,channel); 658a30fec6bcaca00206491523e7b7b59e707f15339cristy if ((traits == UndefinedPixelTrait) || 659a30fec6bcaca00206491523e7b7b59e707f15339cristy (evaluate_traits == UndefinedPixelTrait)) 660a30fec6bcaca00206491523e7b7b59e707f15339cristy continue; 661a30fec6bcaca00206491523e7b7b59e707f15339cristy if ((traits & UpdatePixelTrait) == 0) 662a30fec6bcaca00206491523e7b7b59e707f15339cristy continue; 663a30fec6bcaca00206491523e7b7b59e707f15339cristy evaluate_pixel[x].channel[i]=ApplyEvaluateOperator( 664e7704276d758791b63a64832735480860086f104cristy random_info[id],GetPixelChannel(image,channel,p),j == 0 ? 665e7704276d758791b63a64832735480860086f104cristy AddEvaluateOperator : op,evaluate_pixel[x].channel[i]); 666a30fec6bcaca00206491523e7b7b59e707f15339cristy } 667a30fec6bcaca00206491523e7b7b59e707f15339cristy p+=GetPixelChannels(next); 668ba18a7a20da567238922ea992832fd3c8f70e7bbcristy } 66908a3d70530ab973a425c8cdce82396825b6a7834cristy image_view=DestroyCacheView(image_view); 67008a3d70530ab973a425c8cdce82396825b6a7834cristy next=GetNextImageInList(next); 67108a3d70530ab973a425c8cdce82396825b6a7834cristy } 6724ee2b0c11849aca22cbc22f1fb48e3ee9c8eaba5cristy for (x=0; x < (ssize_t) image->columns; x++) 67308a3d70530ab973a425c8cdce82396825b6a7834cristy { 674a30fec6bcaca00206491523e7b7b59e707f15339cristy register ssize_t 675a30fec6bcaca00206491523e7b7b59e707f15339cristy i; 67608a3d70530ab973a425c8cdce82396825b6a7834cristy 677a30fec6bcaca00206491523e7b7b59e707f15339cristy switch (op) 67808a3d70530ab973a425c8cdce82396825b6a7834cristy { 679a30fec6bcaca00206491523e7b7b59e707f15339cristy case MeanEvaluateOperator: 680a30fec6bcaca00206491523e7b7b59e707f15339cristy { 6814ee2b0c11849aca22cbc22f1fb48e3ee9c8eaba5cristy for (i=0; i < (ssize_t) GetPixelChannels(image); i++) 682a19f1d70e9a9f88279c4ecafe6dfafc1f9a09599cristy evaluate_pixel[x].channel[i]/=(double) number_images; 683a30fec6bcaca00206491523e7b7b59e707f15339cristy break; 684a30fec6bcaca00206491523e7b7b59e707f15339cristy } 685a30fec6bcaca00206491523e7b7b59e707f15339cristy case MultiplyEvaluateOperator: 686a30fec6bcaca00206491523e7b7b59e707f15339cristy { 6874ee2b0c11849aca22cbc22f1fb48e3ee9c8eaba5cristy for (i=0; i < (ssize_t) GetPixelChannels(image); i++) 688a30fec6bcaca00206491523e7b7b59e707f15339cristy { 689a30fec6bcaca00206491523e7b7b59e707f15339cristy register ssize_t 690a30fec6bcaca00206491523e7b7b59e707f15339cristy j; 691a30fec6bcaca00206491523e7b7b59e707f15339cristy 692a30fec6bcaca00206491523e7b7b59e707f15339cristy for (j=0; j < (ssize_t) (number_images-1); j++) 693a30fec6bcaca00206491523e7b7b59e707f15339cristy evaluate_pixel[x].channel[i]*=QuantumScale; 694a30fec6bcaca00206491523e7b7b59e707f15339cristy } 695a30fec6bcaca00206491523e7b7b59e707f15339cristy break; 696a30fec6bcaca00206491523e7b7b59e707f15339cristy } 6977c4c78fe1a6a4884ad06dcf886cd1f6a40cc037ccristy case RootMeanSquareEvaluateOperator: 6987c4c78fe1a6a4884ad06dcf886cd1f6a40cc037ccristy { 6997c4c78fe1a6a4884ad06dcf886cd1f6a40cc037ccristy for (i=0; i < (ssize_t) GetPixelChannels(image); i++) 7007c4c78fe1a6a4884ad06dcf886cd1f6a40cc037ccristy evaluate_pixel[x].channel[i]=sqrt(evaluate_pixel[x].channel[i]/ 7017c4c78fe1a6a4884ad06dcf886cd1f6a40cc037ccristy number_images); 7027c4c78fe1a6a4884ad06dcf886cd1f6a40cc037ccristy break; 7037c4c78fe1a6a4884ad06dcf886cd1f6a40cc037ccristy } 704a30fec6bcaca00206491523e7b7b59e707f15339cristy default: 705a30fec6bcaca00206491523e7b7b59e707f15339cristy break; 70608a3d70530ab973a425c8cdce82396825b6a7834cristy } 707a30fec6bcaca00206491523e7b7b59e707f15339cristy } 7084ee2b0c11849aca22cbc22f1fb48e3ee9c8eaba5cristy for (x=0; x < (ssize_t) image->columns; x++) 70908a3d70530ab973a425c8cdce82396825b6a7834cristy { 710ba18a7a20da567238922ea992832fd3c8f70e7bbcristy register ssize_t 711ba18a7a20da567238922ea992832fd3c8f70e7bbcristy i; 712ba18a7a20da567238922ea992832fd3c8f70e7bbcristy 713883fde11debec15cedb05dc5d7228d8588066bc0cristy if (GetPixelReadMask(image,q) == 0) 71410a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy { 7154ee2b0c11849aca22cbc22f1fb48e3ee9c8eaba5cristy q+=GetPixelChannels(image); 71610a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy continue; 71710a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy } 7184ee2b0c11849aca22cbc22f1fb48e3ee9c8eaba5cristy for (i=0; i < (ssize_t) GetPixelChannels(image); i++) 719ba18a7a20da567238922ea992832fd3c8f70e7bbcristy { 7205a23c55ddcfdf6ae717dd42d8a1c1a2ff8c6305fcristy PixelChannel channel=GetPixelChannelChannel(image,i); 7215a23c55ddcfdf6ae717dd42d8a1c1a2ff8c6305fcristy PixelTrait traits=GetPixelChannelTraits(image,channel); 722a30fec6bcaca00206491523e7b7b59e707f15339cristy if (traits == UndefinedPixelTrait) 723ba18a7a20da567238922ea992832fd3c8f70e7bbcristy continue; 724ba18a7a20da567238922ea992832fd3c8f70e7bbcristy if ((traits & UpdatePixelTrait) == 0) 725ba18a7a20da567238922ea992832fd3c8f70e7bbcristy continue; 726a30fec6bcaca00206491523e7b7b59e707f15339cristy q[i]=ClampToQuantum(evaluate_pixel[x].channel[i]); 727ba18a7a20da567238922ea992832fd3c8f70e7bbcristy } 7284ee2b0c11849aca22cbc22f1fb48e3ee9c8eaba5cristy q+=GetPixelChannels(image); 72908a3d70530ab973a425c8cdce82396825b6a7834cristy } 730a30fec6bcaca00206491523e7b7b59e707f15339cristy if (SyncCacheViewAuthenticPixels(evaluate_view,exception) == MagickFalse) 731a30fec6bcaca00206491523e7b7b59e707f15339cristy status=MagickFalse; 732a30fec6bcaca00206491523e7b7b59e707f15339cristy if (images->progress_monitor != (MagickProgressMonitor) NULL) 7339ee911ca8bd048eb050184ee491f631f947a6a8dcristy { 734a30fec6bcaca00206491523e7b7b59e707f15339cristy MagickBooleanType 735a30fec6bcaca00206491523e7b7b59e707f15339cristy proceed; 736ba18a7a20da567238922ea992832fd3c8f70e7bbcristy 737a30fec6bcaca00206491523e7b7b59e707f15339cristy#if defined(MAGICKCORE_OPENMP_SUPPORT) 738a30fec6bcaca00206491523e7b7b59e707f15339cristy #pragma omp critical (MagickCore_EvaluateImages) 739a30fec6bcaca00206491523e7b7b59e707f15339cristy#endif 740a30fec6bcaca00206491523e7b7b59e707f15339cristy proceed=SetImageProgress(images,EvaluateImageTag,progress++, 7414ee2b0c11849aca22cbc22f1fb48e3ee9c8eaba5cristy image->rows); 742a30fec6bcaca00206491523e7b7b59e707f15339cristy if (proceed == MagickFalse) 743a30fec6bcaca00206491523e7b7b59e707f15339cristy status=MagickFalse; 7449ee911ca8bd048eb050184ee491f631f947a6a8dcristy } 7459ee911ca8bd048eb050184ee491f631f947a6a8dcristy } 74608a3d70530ab973a425c8cdce82396825b6a7834cristy } 747d18ae7ce9b6ff934472abb8e3fa73d0c1aed7d20cristy evaluate_view=DestroyCacheView(evaluate_view); 748d18ae7ce9b6ff934472abb8e3fa73d0c1aed7d20cristy evaluate_pixels=DestroyPixelThreadSet(evaluate_pixels); 749d18ae7ce9b6ff934472abb8e3fa73d0c1aed7d20cristy random_info=DestroyRandomInfoThreadSet(random_info); 750d18ae7ce9b6ff934472abb8e3fa73d0c1aed7d20cristy if (status == MagickFalse) 7514ee2b0c11849aca22cbc22f1fb48e3ee9c8eaba5cristy image=DestroyImage(image); 7524ee2b0c11849aca22cbc22f1fb48e3ee9c8eaba5cristy return(image); 753d18ae7ce9b6ff934472abb8e3fa73d0c1aed7d20cristy} 754d18ae7ce9b6ff934472abb8e3fa73d0c1aed7d20cristy 755d42d995b9cb2a16e13221e665554417a5b7ec7fbcristyMagickExport MagickBooleanType EvaluateImage(Image *image, 756d42d995b9cb2a16e13221e665554417a5b7ec7fbcristy const MagickEvaluateOperator op,const double value,ExceptionInfo *exception) 757351842fbf91597bd44b6200df92c8d45c98fe5adcristy{ 758351842fbf91597bd44b6200df92c8d45c98fe5adcristy CacheView 759351842fbf91597bd44b6200df92c8d45c98fe5adcristy *image_view; 760351842fbf91597bd44b6200df92c8d45c98fe5adcristy 761351842fbf91597bd44b6200df92c8d45c98fe5adcristy MagickBooleanType 762351842fbf91597bd44b6200df92c8d45c98fe5adcristy status; 763351842fbf91597bd44b6200df92c8d45c98fe5adcristy 7645f959473f334e196c6bf39b740c12cb4963fceebcristy MagickOffsetType 7655f959473f334e196c6bf39b740c12cb4963fceebcristy progress; 7665f959473f334e196c6bf39b740c12cb4963fceebcristy 767351842fbf91597bd44b6200df92c8d45c98fe5adcristy RandomInfo 76805d2ff7ebf21f659f5b11e45afb294e152f4330cdirk **magick_restrict random_info; 769351842fbf91597bd44b6200df92c8d45c98fe5adcristy 7705f959473f334e196c6bf39b740c12cb4963fceebcristy ssize_t 7715f959473f334e196c6bf39b740c12cb4963fceebcristy y; 7725f959473f334e196c6bf39b740c12cb4963fceebcristy 773b36143ff2559783289b92a25d4b4579a6a8b5618glennrp#if defined(MAGICKCORE_OPENMP_SUPPORT) 77457340e008c81f05c0adb4d8874dda11104d8bb7ecristy unsigned long 77557340e008c81f05c0adb4d8874dda11104d8bb7ecristy key; 776b36143ff2559783289b92a25d4b4579a6a8b5618glennrp#endif 77757340e008c81f05c0adb4d8874dda11104d8bb7ecristy 778351842fbf91597bd44b6200df92c8d45c98fe5adcristy assert(image != (Image *) NULL); 779e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy assert(image->signature == MagickCoreSignature); 780351842fbf91597bd44b6200df92c8d45c98fe5adcristy if (image->debug != MagickFalse) 781351842fbf91597bd44b6200df92c8d45c98fe5adcristy (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); 782351842fbf91597bd44b6200df92c8d45c98fe5adcristy assert(exception != (ExceptionInfo *) NULL); 783e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy assert(exception->signature == MagickCoreSignature); 784574cc26500992189f637cd1cdf93d0654e7df7aecristy if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse) 785574cc26500992189f637cd1cdf93d0654e7df7aecristy return(MagickFalse); 786351842fbf91597bd44b6200df92c8d45c98fe5adcristy status=MagickTrue; 787351842fbf91597bd44b6200df92c8d45c98fe5adcristy progress=0; 788351842fbf91597bd44b6200df92c8d45c98fe5adcristy random_info=AcquireRandomInfoThreadSet(); 78946ff2676b1044ea4101ac7a59b83289cd8f6cfdacristy image_view=AcquireAuthenticCacheView(image,exception); 790351842fbf91597bd44b6200df92c8d45c98fe5adcristy#if defined(MAGICKCORE_OPENMP_SUPPORT) 791ecd6dd161dfefd2b14a11c3d907bdeb648f5e201cristy key=GetRandomSecretKey(random_info[0]); 79257340e008c81f05c0adb4d8874dda11104d8bb7ecristy #pragma omp parallel for schedule(static,4) shared(progress,status) \ 7935e6b259130f9dbe0da4666f734937017babe573acristy magick_threads(image,image,image->rows,key == ~0UL) 794351842fbf91597bd44b6200df92c8d45c98fe5adcristy#endif 795bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy for (y=0; y < (ssize_t) image->rows; y++) 796351842fbf91597bd44b6200df92c8d45c98fe5adcristy { 7975c9e6f2ec2e7738ede83902931da0f80db60f565cristy const int 7985c9e6f2ec2e7738ede83902931da0f80db60f565cristy id = GetOpenMPThreadId(); 7996ebe97c3470475a87f649cfab09fa0cf1f249da3cristy 8004c08aed51c5899665ade97263692328eea4af106cristy register Quantum 80105d2ff7ebf21f659f5b11e45afb294e152f4330cdirk *magick_restrict q; 802351842fbf91597bd44b6200df92c8d45c98fe5adcristy 8035c9e6f2ec2e7738ede83902931da0f80db60f565cristy register ssize_t 8045c9e6f2ec2e7738ede83902931da0f80db60f565cristy x; 8055c9e6f2ec2e7738ede83902931da0f80db60f565cristy 806351842fbf91597bd44b6200df92c8d45c98fe5adcristy if (status == MagickFalse) 807351842fbf91597bd44b6200df92c8d45c98fe5adcristy continue; 808351842fbf91597bd44b6200df92c8d45c98fe5adcristy q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception); 809acd2ed254c18c254a0ab5aafa06d1645e5d079d8cristy if (q == (Quantum *) NULL) 810351842fbf91597bd44b6200df92c8d45c98fe5adcristy { 811351842fbf91597bd44b6200df92c8d45c98fe5adcristy status=MagickFalse; 812351842fbf91597bd44b6200df92c8d45c98fe5adcristy continue; 813351842fbf91597bd44b6200df92c8d45c98fe5adcristy } 814bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy for (x=0; x < (ssize_t) image->columns; x++) 815351842fbf91597bd44b6200df92c8d45c98fe5adcristy { 8162f5eaba185a3514cb1d704ea48c72cfa929da3fdcristy double 8172f5eaba185a3514cb1d704ea48c72cfa929da3fdcristy result; 8182f5eaba185a3514cb1d704ea48c72cfa929da3fdcristy 81949dd6a0c1bab5e1e6f99369c0f70a5e0184810d4cristy register ssize_t 82049dd6a0c1bab5e1e6f99369c0f70a5e0184810d4cristy i; 82149dd6a0c1bab5e1e6f99369c0f70a5e0184810d4cristy 82249dd6a0c1bab5e1e6f99369c0f70a5e0184810d4cristy for (i=0; i < (ssize_t) GetPixelChannels(image); i++) 82349dd6a0c1bab5e1e6f99369c0f70a5e0184810d4cristy { 8245a23c55ddcfdf6ae717dd42d8a1c1a2ff8c6305fcristy PixelChannel channel=GetPixelChannelChannel(image,i); 8255a23c55ddcfdf6ae717dd42d8a1c1a2ff8c6305fcristy PixelTrait traits=GetPixelChannelTraits(image,channel); 82649dd6a0c1bab5e1e6f99369c0f70a5e0184810d4cristy if (traits == UndefinedPixelTrait) 82749dd6a0c1bab5e1e6f99369c0f70a5e0184810d4cristy continue; 8281eced097f7f4f51d5aa14d46079292fa1dcf0e77cristy if (((traits & CopyPixelTrait) != 0) || 829883fde11debec15cedb05dc5d7228d8588066bc0cristy (GetPixelReadMask(image,q) == 0)) 830177e41c20ccba692bc4c7797aeb817b2f80c7e8ccristy continue; 8312f5eaba185a3514cb1d704ea48c72cfa929da3fdcristy result=ApplyEvaluateOperator(random_info[id],q[i],op,value); 8322f5eaba185a3514cb1d704ea48c72cfa929da3fdcristy if (op == MeanEvaluateOperator) 8332f5eaba185a3514cb1d704ea48c72cfa929da3fdcristy result/=2.0; 8342f5eaba185a3514cb1d704ea48c72cfa929da3fdcristy q[i]=ClampToQuantum(result); 83549dd6a0c1bab5e1e6f99369c0f70a5e0184810d4cristy } 836ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy q+=GetPixelChannels(image); 837351842fbf91597bd44b6200df92c8d45c98fe5adcristy } 838351842fbf91597bd44b6200df92c8d45c98fe5adcristy if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse) 839351842fbf91597bd44b6200df92c8d45c98fe5adcristy status=MagickFalse; 840351842fbf91597bd44b6200df92c8d45c98fe5adcristy if (image->progress_monitor != (MagickProgressMonitor) NULL) 841351842fbf91597bd44b6200df92c8d45c98fe5adcristy { 842351842fbf91597bd44b6200df92c8d45c98fe5adcristy MagickBooleanType 843351842fbf91597bd44b6200df92c8d45c98fe5adcristy proceed; 844351842fbf91597bd44b6200df92c8d45c98fe5adcristy 845351842fbf91597bd44b6200df92c8d45c98fe5adcristy#if defined(MAGICKCORE_OPENMP_SUPPORT) 846ac245f8a51ea65b085d751c41d8ca4b426bdfe5bcristy #pragma omp critical (MagickCore_EvaluateImage) 847351842fbf91597bd44b6200df92c8d45c98fe5adcristy#endif 848351842fbf91597bd44b6200df92c8d45c98fe5adcristy proceed=SetImageProgress(image,EvaluateImageTag,progress++,image->rows); 849351842fbf91597bd44b6200df92c8d45c98fe5adcristy if (proceed == MagickFalse) 850351842fbf91597bd44b6200df92c8d45c98fe5adcristy status=MagickFalse; 851351842fbf91597bd44b6200df92c8d45c98fe5adcristy } 852351842fbf91597bd44b6200df92c8d45c98fe5adcristy } 853351842fbf91597bd44b6200df92c8d45c98fe5adcristy image_view=DestroyCacheView(image_view); 854351842fbf91597bd44b6200df92c8d45c98fe5adcristy random_info=DestroyRandomInfoThreadSet(random_info); 855351842fbf91597bd44b6200df92c8d45c98fe5adcristy return(status); 856351842fbf91597bd44b6200df92c8d45c98fe5adcristy} 857351842fbf91597bd44b6200df92c8d45c98fe5adcristy 858351842fbf91597bd44b6200df92c8d45c98fe5adcristy/* 859351842fbf91597bd44b6200df92c8d45c98fe5adcristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 860351842fbf91597bd44b6200df92c8d45c98fe5adcristy% % 861351842fbf91597bd44b6200df92c8d45c98fe5adcristy% % 862351842fbf91597bd44b6200df92c8d45c98fe5adcristy% % 863351842fbf91597bd44b6200df92c8d45c98fe5adcristy% F u n c t i o n I m a g e % 864351842fbf91597bd44b6200df92c8d45c98fe5adcristy% % 865351842fbf91597bd44b6200df92c8d45c98fe5adcristy% % 866351842fbf91597bd44b6200df92c8d45c98fe5adcristy% % 867351842fbf91597bd44b6200df92c8d45c98fe5adcristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 868351842fbf91597bd44b6200df92c8d45c98fe5adcristy% 869351842fbf91597bd44b6200df92c8d45c98fe5adcristy% FunctionImage() applies a value to the image with an arithmetic, relational, 870351842fbf91597bd44b6200df92c8d45c98fe5adcristy% or logical operator to an image. Use these operations to lighten or darken 871351842fbf91597bd44b6200df92c8d45c98fe5adcristy% an image, to increase or decrease contrast in an image, or to produce the 872351842fbf91597bd44b6200df92c8d45c98fe5adcristy% "negative" of an image. 873351842fbf91597bd44b6200df92c8d45c98fe5adcristy% 874d42d995b9cb2a16e13221e665554417a5b7ec7fbcristy% The format of the FunctionImage method is: 875351842fbf91597bd44b6200df92c8d45c98fe5adcristy% 876351842fbf91597bd44b6200df92c8d45c98fe5adcristy% MagickBooleanType FunctionImage(Image *image, 877bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy% const MagickFunction function,const ssize_t number_parameters, 878351842fbf91597bd44b6200df92c8d45c98fe5adcristy% const double *parameters,ExceptionInfo *exception) 879351842fbf91597bd44b6200df92c8d45c98fe5adcristy% 880351842fbf91597bd44b6200df92c8d45c98fe5adcristy% A description of each parameter follows: 881351842fbf91597bd44b6200df92c8d45c98fe5adcristy% 882351842fbf91597bd44b6200df92c8d45c98fe5adcristy% o image: the image. 883351842fbf91597bd44b6200df92c8d45c98fe5adcristy% 884351842fbf91597bd44b6200df92c8d45c98fe5adcristy% o function: A channel function. 885351842fbf91597bd44b6200df92c8d45c98fe5adcristy% 886351842fbf91597bd44b6200df92c8d45c98fe5adcristy% o parameters: one or more parameters. 887351842fbf91597bd44b6200df92c8d45c98fe5adcristy% 888351842fbf91597bd44b6200df92c8d45c98fe5adcristy% o exception: return any errors or warnings in this structure. 889351842fbf91597bd44b6200df92c8d45c98fe5adcristy% 890351842fbf91597bd44b6200df92c8d45c98fe5adcristy*/ 891351842fbf91597bd44b6200df92c8d45c98fe5adcristy 892351842fbf91597bd44b6200df92c8d45c98fe5adcristystatic Quantum ApplyFunction(Quantum pixel,const MagickFunction function, 893bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy const size_t number_parameters,const double *parameters, 894351842fbf91597bd44b6200df92c8d45c98fe5adcristy ExceptionInfo *exception) 895351842fbf91597bd44b6200df92c8d45c98fe5adcristy{ 896a19f1d70e9a9f88279c4ecafe6dfafc1f9a09599cristy double 897351842fbf91597bd44b6200df92c8d45c98fe5adcristy result; 898351842fbf91597bd44b6200df92c8d45c98fe5adcristy 899bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy register ssize_t 900351842fbf91597bd44b6200df92c8d45c98fe5adcristy i; 901351842fbf91597bd44b6200df92c8d45c98fe5adcristy 902351842fbf91597bd44b6200df92c8d45c98fe5adcristy (void) exception; 903351842fbf91597bd44b6200df92c8d45c98fe5adcristy result=0.0; 904351842fbf91597bd44b6200df92c8d45c98fe5adcristy switch (function) 905351842fbf91597bd44b6200df92c8d45c98fe5adcristy { 906351842fbf91597bd44b6200df92c8d45c98fe5adcristy case PolynomialFunction: 907351842fbf91597bd44b6200df92c8d45c98fe5adcristy { 908351842fbf91597bd44b6200df92c8d45c98fe5adcristy /* 909e2a912b6c9086c98ec838baa0824cd8deca55538cristy Polynomial: polynomial constants, highest to lowest order (e.g. c0*x^3+ 910e2a912b6c9086c98ec838baa0824cd8deca55538cristy c1*x^2+c2*x+c3). 91194a757875f6ef9dcbbc4f97bbca32b736d28de4ecristy */ 912351842fbf91597bd44b6200df92c8d45c98fe5adcristy result=0.0; 913bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy for (i=0; i < (ssize_t) number_parameters; i++) 91494a757875f6ef9dcbbc4f97bbca32b736d28de4ecristy result=result*QuantumScale*pixel+parameters[i]; 91594a757875f6ef9dcbbc4f97bbca32b736d28de4ecristy result*=QuantumRange; 916351842fbf91597bd44b6200df92c8d45c98fe5adcristy break; 917351842fbf91597bd44b6200df92c8d45c98fe5adcristy } 918351842fbf91597bd44b6200df92c8d45c98fe5adcristy case SinusoidFunction: 919351842fbf91597bd44b6200df92c8d45c98fe5adcristy { 920a19f1d70e9a9f88279c4ecafe6dfafc1f9a09599cristy double 92194a757875f6ef9dcbbc4f97bbca32b736d28de4ecristy amplitude, 92294a757875f6ef9dcbbc4f97bbca32b736d28de4ecristy bias, 92394a757875f6ef9dcbbc4f97bbca32b736d28de4ecristy frequency, 92494a757875f6ef9dcbbc4f97bbca32b736d28de4ecristy phase; 92594a757875f6ef9dcbbc4f97bbca32b736d28de4ecristy 92694a757875f6ef9dcbbc4f97bbca32b736d28de4ecristy /* 92794a757875f6ef9dcbbc4f97bbca32b736d28de4ecristy Sinusoid: frequency, phase, amplitude, bias. 92894a757875f6ef9dcbbc4f97bbca32b736d28de4ecristy */ 92994a757875f6ef9dcbbc4f97bbca32b736d28de4ecristy frequency=(number_parameters >= 1) ? parameters[0] : 1.0; 93094a757875f6ef9dcbbc4f97bbca32b736d28de4ecristy phase=(number_parameters >= 2) ? parameters[1] : 0.0; 93194a757875f6ef9dcbbc4f97bbca32b736d28de4ecristy amplitude=(number_parameters >= 3) ? parameters[2] : 0.5; 93294a757875f6ef9dcbbc4f97bbca32b736d28de4ecristy bias=(number_parameters >= 4) ? parameters[3] : 0.5; 933a19f1d70e9a9f88279c4ecafe6dfafc1f9a09599cristy result=(double) (QuantumRange*(amplitude*sin((double) (2.0* 93494a757875f6ef9dcbbc4f97bbca32b736d28de4ecristy MagickPI*(frequency*QuantumScale*pixel+phase/360.0)))+bias)); 935351842fbf91597bd44b6200df92c8d45c98fe5adcristy break; 936351842fbf91597bd44b6200df92c8d45c98fe5adcristy } 937351842fbf91597bd44b6200df92c8d45c98fe5adcristy case ArcsinFunction: 938351842fbf91597bd44b6200df92c8d45c98fe5adcristy { 939a19f1d70e9a9f88279c4ecafe6dfafc1f9a09599cristy double 94094a757875f6ef9dcbbc4f97bbca32b736d28de4ecristy bias, 94194a757875f6ef9dcbbc4f97bbca32b736d28de4ecristy center, 94294a757875f6ef9dcbbc4f97bbca32b736d28de4ecristy range, 94394a757875f6ef9dcbbc4f97bbca32b736d28de4ecristy width; 94494a757875f6ef9dcbbc4f97bbca32b736d28de4ecristy 94594a757875f6ef9dcbbc4f97bbca32b736d28de4ecristy /* 946e2a912b6c9086c98ec838baa0824cd8deca55538cristy Arcsin (peged at range limits for invalid results): width, center, 947e2a912b6c9086c98ec838baa0824cd8deca55538cristy range, and bias. 94894a757875f6ef9dcbbc4f97bbca32b736d28de4ecristy */ 94994a757875f6ef9dcbbc4f97bbca32b736d28de4ecristy width=(number_parameters >= 1) ? parameters[0] : 1.0; 95094a757875f6ef9dcbbc4f97bbca32b736d28de4ecristy center=(number_parameters >= 2) ? parameters[1] : 0.5; 95194a757875f6ef9dcbbc4f97bbca32b736d28de4ecristy range=(number_parameters >= 3) ? parameters[2] : 1.0; 95294a757875f6ef9dcbbc4f97bbca32b736d28de4ecristy bias=(number_parameters >= 4) ? parameters[3] : 0.5; 95394a757875f6ef9dcbbc4f97bbca32b736d28de4ecristy result=2.0/width*(QuantumScale*pixel-center); 954351842fbf91597bd44b6200df92c8d45c98fe5adcristy if ( result <= -1.0 ) 95594a757875f6ef9dcbbc4f97bbca32b736d28de4ecristy result=bias-range/2.0; 956351842fbf91597bd44b6200df92c8d45c98fe5adcristy else 95794a757875f6ef9dcbbc4f97bbca32b736d28de4ecristy if (result >= 1.0) 95894a757875f6ef9dcbbc4f97bbca32b736d28de4ecristy result=bias+range/2.0; 95994a757875f6ef9dcbbc4f97bbca32b736d28de4ecristy else 960a19f1d70e9a9f88279c4ecafe6dfafc1f9a09599cristy result=(double) (range/MagickPI*asin((double) result)+bias); 96194a757875f6ef9dcbbc4f97bbca32b736d28de4ecristy result*=QuantumRange; 962351842fbf91597bd44b6200df92c8d45c98fe5adcristy break; 963351842fbf91597bd44b6200df92c8d45c98fe5adcristy } 964351842fbf91597bd44b6200df92c8d45c98fe5adcristy case ArctanFunction: 965351842fbf91597bd44b6200df92c8d45c98fe5adcristy { 966a19f1d70e9a9f88279c4ecafe6dfafc1f9a09599cristy double 96794a757875f6ef9dcbbc4f97bbca32b736d28de4ecristy center, 96894a757875f6ef9dcbbc4f97bbca32b736d28de4ecristy bias, 96994a757875f6ef9dcbbc4f97bbca32b736d28de4ecristy range, 97094a757875f6ef9dcbbc4f97bbca32b736d28de4ecristy slope; 97194a757875f6ef9dcbbc4f97bbca32b736d28de4ecristy 97294a757875f6ef9dcbbc4f97bbca32b736d28de4ecristy /* 97394a757875f6ef9dcbbc4f97bbca32b736d28de4ecristy Arctan: slope, center, range, and bias. 97494a757875f6ef9dcbbc4f97bbca32b736d28de4ecristy */ 97594a757875f6ef9dcbbc4f97bbca32b736d28de4ecristy slope=(number_parameters >= 1) ? parameters[0] : 1.0; 97694a757875f6ef9dcbbc4f97bbca32b736d28de4ecristy center=(number_parameters >= 2) ? parameters[1] : 0.5; 97794a757875f6ef9dcbbc4f97bbca32b736d28de4ecristy range=(number_parameters >= 3) ? parameters[2] : 1.0; 97894a757875f6ef9dcbbc4f97bbca32b736d28de4ecristy bias=(number_parameters >= 4) ? parameters[3] : 0.5; 979a19f1d70e9a9f88279c4ecafe6dfafc1f9a09599cristy result=(double) (MagickPI*slope*(QuantumScale*pixel-center)); 980a19f1d70e9a9f88279c4ecafe6dfafc1f9a09599cristy result=(double) (QuantumRange*(range/MagickPI*atan((double) 98194a757875f6ef9dcbbc4f97bbca32b736d28de4ecristy result)+bias)); 982351842fbf91597bd44b6200df92c8d45c98fe5adcristy break; 983351842fbf91597bd44b6200df92c8d45c98fe5adcristy } 984351842fbf91597bd44b6200df92c8d45c98fe5adcristy case UndefinedFunction: 985351842fbf91597bd44b6200df92c8d45c98fe5adcristy break; 986351842fbf91597bd44b6200df92c8d45c98fe5adcristy } 987351842fbf91597bd44b6200df92c8d45c98fe5adcristy return(ClampToQuantum(result)); 988351842fbf91597bd44b6200df92c8d45c98fe5adcristy} 989351842fbf91597bd44b6200df92c8d45c98fe5adcristy 990351842fbf91597bd44b6200df92c8d45c98fe5adcristyMagickExport MagickBooleanType FunctionImage(Image *image, 991bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy const MagickFunction function,const size_t number_parameters, 992351842fbf91597bd44b6200df92c8d45c98fe5adcristy const double *parameters,ExceptionInfo *exception) 993351842fbf91597bd44b6200df92c8d45c98fe5adcristy{ 994351842fbf91597bd44b6200df92c8d45c98fe5adcristy#define FunctionImageTag "Function/Image " 995351842fbf91597bd44b6200df92c8d45c98fe5adcristy 996351842fbf91597bd44b6200df92c8d45c98fe5adcristy CacheView 997351842fbf91597bd44b6200df92c8d45c98fe5adcristy *image_view; 998351842fbf91597bd44b6200df92c8d45c98fe5adcristy 999351842fbf91597bd44b6200df92c8d45c98fe5adcristy MagickBooleanType 1000351842fbf91597bd44b6200df92c8d45c98fe5adcristy status; 1001351842fbf91597bd44b6200df92c8d45c98fe5adcristy 10025f959473f334e196c6bf39b740c12cb4963fceebcristy MagickOffsetType 10035f959473f334e196c6bf39b740c12cb4963fceebcristy progress; 10045f959473f334e196c6bf39b740c12cb4963fceebcristy 10055f959473f334e196c6bf39b740c12cb4963fceebcristy ssize_t 10065f959473f334e196c6bf39b740c12cb4963fceebcristy y; 10075f959473f334e196c6bf39b740c12cb4963fceebcristy 1008351842fbf91597bd44b6200df92c8d45c98fe5adcristy assert(image != (Image *) NULL); 1009e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy assert(image->signature == MagickCoreSignature); 1010351842fbf91597bd44b6200df92c8d45c98fe5adcristy if (image->debug != MagickFalse) 1011351842fbf91597bd44b6200df92c8d45c98fe5adcristy (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); 1012351842fbf91597bd44b6200df92c8d45c98fe5adcristy assert(exception != (ExceptionInfo *) NULL); 1013e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy assert(exception->signature == MagickCoreSignature); 101421dc0310cdaa5cc6034a1e100746706f5ec089ebdirk#if defined(MAGICKCORE_OPENCL_SUPPORT) 101506c4f034881895074da3f4e4f206ba06429f042bdirk if (AccelerateFunctionImage(image,function,number_parameters,parameters, 101606c4f034881895074da3f4e4f206ba06429f042bdirk exception) != MagickFalse) 101794190b79d7abf8261e3a1af37aa7a7f86757b2d6Dusan Veljko return(MagickTrue); 101821dc0310cdaa5cc6034a1e100746706f5ec089ebdirk#endif 1019574cc26500992189f637cd1cdf93d0654e7df7aecristy if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse) 1020574cc26500992189f637cd1cdf93d0654e7df7aecristy return(MagickFalse); 1021351842fbf91597bd44b6200df92c8d45c98fe5adcristy status=MagickTrue; 1022351842fbf91597bd44b6200df92c8d45c98fe5adcristy progress=0; 102346ff2676b1044ea4101ac7a59b83289cd8f6cfdacristy image_view=AcquireAuthenticCacheView(image,exception); 1024351842fbf91597bd44b6200df92c8d45c98fe5adcristy#if defined(MAGICKCORE_OPENMP_SUPPORT) 1025ac245f8a51ea65b085d751c41d8ca4b426bdfe5bcristy #pragma omp parallel for schedule(static,4) shared(progress,status) \ 10265e6b259130f9dbe0da4666f734937017babe573acristy magick_threads(image,image,image->rows,1) 1027351842fbf91597bd44b6200df92c8d45c98fe5adcristy#endif 1028bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy for (y=0; y < (ssize_t) image->rows; y++) 1029351842fbf91597bd44b6200df92c8d45c98fe5adcristy { 10304c08aed51c5899665ade97263692328eea4af106cristy register Quantum 103105d2ff7ebf21f659f5b11e45afb294e152f4330cdirk *magick_restrict q; 1032351842fbf91597bd44b6200df92c8d45c98fe5adcristy 103394a757875f6ef9dcbbc4f97bbca32b736d28de4ecristy register ssize_t 103494a757875f6ef9dcbbc4f97bbca32b736d28de4ecristy x; 103594a757875f6ef9dcbbc4f97bbca32b736d28de4ecristy 1036351842fbf91597bd44b6200df92c8d45c98fe5adcristy if (status == MagickFalse) 1037351842fbf91597bd44b6200df92c8d45c98fe5adcristy continue; 1038351842fbf91597bd44b6200df92c8d45c98fe5adcristy q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception); 1039acd2ed254c18c254a0ab5aafa06d1645e5d079d8cristy if (q == (Quantum *) NULL) 1040351842fbf91597bd44b6200df92c8d45c98fe5adcristy { 1041351842fbf91597bd44b6200df92c8d45c98fe5adcristy status=MagickFalse; 1042351842fbf91597bd44b6200df92c8d45c98fe5adcristy continue; 1043351842fbf91597bd44b6200df92c8d45c98fe5adcristy } 1044bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy for (x=0; x < (ssize_t) image->columns; x++) 1045351842fbf91597bd44b6200df92c8d45c98fe5adcristy { 104694a757875f6ef9dcbbc4f97bbca32b736d28de4ecristy register ssize_t 104794a757875f6ef9dcbbc4f97bbca32b736d28de4ecristy i; 104894a757875f6ef9dcbbc4f97bbca32b736d28de4ecristy 1049883fde11debec15cedb05dc5d7228d8588066bc0cristy if (GetPixelReadMask(image,q) == 0) 105010a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy { 105110a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy q+=GetPixelChannels(image); 105210a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy continue; 105310a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy } 105494a757875f6ef9dcbbc4f97bbca32b736d28de4ecristy for (i=0; i < (ssize_t) GetPixelChannels(image); i++) 105594a757875f6ef9dcbbc4f97bbca32b736d28de4ecristy { 10565a23c55ddcfdf6ae717dd42d8a1c1a2ff8c6305fcristy PixelChannel channel=GetPixelChannelChannel(image,i); 10575a23c55ddcfdf6ae717dd42d8a1c1a2ff8c6305fcristy PixelTrait traits=GetPixelChannelTraits(image,channel); 105894a757875f6ef9dcbbc4f97bbca32b736d28de4ecristy if (traits == UndefinedPixelTrait) 105994a757875f6ef9dcbbc4f97bbca32b736d28de4ecristy continue; 106094a757875f6ef9dcbbc4f97bbca32b736d28de4ecristy if ((traits & UpdatePixelTrait) == 0) 106194a757875f6ef9dcbbc4f97bbca32b736d28de4ecristy continue; 106294a757875f6ef9dcbbc4f97bbca32b736d28de4ecristy q[i]=ApplyFunction(q[i],function,number_parameters,parameters, 106394a757875f6ef9dcbbc4f97bbca32b736d28de4ecristy exception); 106494a757875f6ef9dcbbc4f97bbca32b736d28de4ecristy } 1065ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy q+=GetPixelChannels(image); 1066351842fbf91597bd44b6200df92c8d45c98fe5adcristy } 1067351842fbf91597bd44b6200df92c8d45c98fe5adcristy if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse) 1068351842fbf91597bd44b6200df92c8d45c98fe5adcristy status=MagickFalse; 1069351842fbf91597bd44b6200df92c8d45c98fe5adcristy if (image->progress_monitor != (MagickProgressMonitor) NULL) 1070351842fbf91597bd44b6200df92c8d45c98fe5adcristy { 1071351842fbf91597bd44b6200df92c8d45c98fe5adcristy MagickBooleanType 1072351842fbf91597bd44b6200df92c8d45c98fe5adcristy proceed; 1073351842fbf91597bd44b6200df92c8d45c98fe5adcristy 1074351842fbf91597bd44b6200df92c8d45c98fe5adcristy#if defined(MAGICKCORE_OPENMP_SUPPORT) 1075ac245f8a51ea65b085d751c41d8ca4b426bdfe5bcristy #pragma omp critical (MagickCore_FunctionImage) 1076351842fbf91597bd44b6200df92c8d45c98fe5adcristy#endif 1077351842fbf91597bd44b6200df92c8d45c98fe5adcristy proceed=SetImageProgress(image,FunctionImageTag,progress++,image->rows); 1078351842fbf91597bd44b6200df92c8d45c98fe5adcristy if (proceed == MagickFalse) 1079351842fbf91597bd44b6200df92c8d45c98fe5adcristy status=MagickFalse; 1080351842fbf91597bd44b6200df92c8d45c98fe5adcristy } 1081351842fbf91597bd44b6200df92c8d45c98fe5adcristy } 1082351842fbf91597bd44b6200df92c8d45c98fe5adcristy image_view=DestroyCacheView(image_view); 1083351842fbf91597bd44b6200df92c8d45c98fe5adcristy return(status); 1084351842fbf91597bd44b6200df92c8d45c98fe5adcristy} 1085351842fbf91597bd44b6200df92c8d45c98fe5adcristy 1086351842fbf91597bd44b6200df92c8d45c98fe5adcristy/* 1087351842fbf91597bd44b6200df92c8d45c98fe5adcristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1088351842fbf91597bd44b6200df92c8d45c98fe5adcristy% % 1089351842fbf91597bd44b6200df92c8d45c98fe5adcristy% % 1090351842fbf91597bd44b6200df92c8d45c98fe5adcristy% % 109150908ac2139298d3f39d279d75c5868caea64316cristy% G e t I m a g e E n t r o p y % 109250908ac2139298d3f39d279d75c5868caea64316cristy% % 109350908ac2139298d3f39d279d75c5868caea64316cristy% % 109450908ac2139298d3f39d279d75c5868caea64316cristy% % 109550908ac2139298d3f39d279d75c5868caea64316cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 109650908ac2139298d3f39d279d75c5868caea64316cristy% 109750908ac2139298d3f39d279d75c5868caea64316cristy% GetImageEntropy() returns the entropy of one or more image channels. 109850908ac2139298d3f39d279d75c5868caea64316cristy% 109950908ac2139298d3f39d279d75c5868caea64316cristy% The format of the GetImageEntropy method is: 110050908ac2139298d3f39d279d75c5868caea64316cristy% 110150908ac2139298d3f39d279d75c5868caea64316cristy% MagickBooleanType GetImageEntropy(const Image *image,double *entropy, 110250908ac2139298d3f39d279d75c5868caea64316cristy% ExceptionInfo *exception) 110350908ac2139298d3f39d279d75c5868caea64316cristy% 110450908ac2139298d3f39d279d75c5868caea64316cristy% A description of each parameter follows: 110550908ac2139298d3f39d279d75c5868caea64316cristy% 110650908ac2139298d3f39d279d75c5868caea64316cristy% o image: the image. 110750908ac2139298d3f39d279d75c5868caea64316cristy% 110850908ac2139298d3f39d279d75c5868caea64316cristy% o entropy: the average entropy of the selected channels. 110950908ac2139298d3f39d279d75c5868caea64316cristy% 111050908ac2139298d3f39d279d75c5868caea64316cristy% o exception: return any errors or warnings in this structure. 111150908ac2139298d3f39d279d75c5868caea64316cristy% 111250908ac2139298d3f39d279d75c5868caea64316cristy*/ 111350908ac2139298d3f39d279d75c5868caea64316cristyMagickExport MagickBooleanType GetImageEntropy(const Image *image, 111450908ac2139298d3f39d279d75c5868caea64316cristy double *entropy,ExceptionInfo *exception) 111550908ac2139298d3f39d279d75c5868caea64316cristy{ 111650908ac2139298d3f39d279d75c5868caea64316cristy double 111750908ac2139298d3f39d279d75c5868caea64316cristy area; 111850908ac2139298d3f39d279d75c5868caea64316cristy 111950908ac2139298d3f39d279d75c5868caea64316cristy ChannelStatistics 112050908ac2139298d3f39d279d75c5868caea64316cristy *channel_statistics; 112150908ac2139298d3f39d279d75c5868caea64316cristy 112250908ac2139298d3f39d279d75c5868caea64316cristy register ssize_t 112350908ac2139298d3f39d279d75c5868caea64316cristy i; 112450908ac2139298d3f39d279d75c5868caea64316cristy 112550908ac2139298d3f39d279d75c5868caea64316cristy assert(image != (Image *) NULL); 1126e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy assert(image->signature == MagickCoreSignature); 112750908ac2139298d3f39d279d75c5868caea64316cristy if (image->debug != MagickFalse) 112850908ac2139298d3f39d279d75c5868caea64316cristy (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); 112950908ac2139298d3f39d279d75c5868caea64316cristy channel_statistics=GetImageStatistics(image,exception); 113050908ac2139298d3f39d279d75c5868caea64316cristy if (channel_statistics == (ChannelStatistics *) NULL) 113150908ac2139298d3f39d279d75c5868caea64316cristy return(MagickFalse); 113250908ac2139298d3f39d279d75c5868caea64316cristy area=0.0; 113350908ac2139298d3f39d279d75c5868caea64316cristy channel_statistics[CompositePixelChannel].entropy=0.0; 113450908ac2139298d3f39d279d75c5868caea64316cristy channel_statistics[CompositePixelChannel].standard_deviation=0.0; 113550908ac2139298d3f39d279d75c5868caea64316cristy for (i=0; i < (ssize_t) GetPixelChannels(image); i++) 113650908ac2139298d3f39d279d75c5868caea64316cristy { 113750908ac2139298d3f39d279d75c5868caea64316cristy PixelChannel channel=GetPixelChannelChannel(image,i); 113850908ac2139298d3f39d279d75c5868caea64316cristy PixelTrait traits=GetPixelChannelTraits(image,channel); 113950908ac2139298d3f39d279d75c5868caea64316cristy if (traits == UndefinedPixelTrait) 114050908ac2139298d3f39d279d75c5868caea64316cristy continue; 114150908ac2139298d3f39d279d75c5868caea64316cristy if ((traits & UpdatePixelTrait) == 0) 114250908ac2139298d3f39d279d75c5868caea64316cristy continue; 114350908ac2139298d3f39d279d75c5868caea64316cristy channel_statistics[CompositePixelChannel].entropy+= 114450908ac2139298d3f39d279d75c5868caea64316cristy channel_statistics[i].entropy; 114550908ac2139298d3f39d279d75c5868caea64316cristy area++; 114650908ac2139298d3f39d279d75c5868caea64316cristy } 114744706661c10e56ccd366f5d48b28f3103ff21e5ecristy if (area > MagickEpsilon) 114844706661c10e56ccd366f5d48b28f3103ff21e5ecristy { 114944706661c10e56ccd366f5d48b28f3103ff21e5ecristy channel_statistics[CompositePixelChannel].entropy/=area; 115044706661c10e56ccd366f5d48b28f3103ff21e5ecristy channel_statistics[CompositePixelChannel].standard_deviation= 115144706661c10e56ccd366f5d48b28f3103ff21e5ecristy sqrt(channel_statistics[CompositePixelChannel].standard_deviation/area); 115244706661c10e56ccd366f5d48b28f3103ff21e5ecristy } 115350908ac2139298d3f39d279d75c5868caea64316cristy *entropy=channel_statistics[CompositePixelChannel].entropy; 115450908ac2139298d3f39d279d75c5868caea64316cristy channel_statistics=(ChannelStatistics *) RelinquishMagickMemory( 115550908ac2139298d3f39d279d75c5868caea64316cristy channel_statistics); 115650908ac2139298d3f39d279d75c5868caea64316cristy return(MagickTrue); 115750908ac2139298d3f39d279d75c5868caea64316cristy} 115850908ac2139298d3f39d279d75c5868caea64316cristy 115950908ac2139298d3f39d279d75c5868caea64316cristy/* 116050908ac2139298d3f39d279d75c5868caea64316cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 116150908ac2139298d3f39d279d75c5868caea64316cristy% % 116250908ac2139298d3f39d279d75c5868caea64316cristy% % 116350908ac2139298d3f39d279d75c5868caea64316cristy% % 1164d42d995b9cb2a16e13221e665554417a5b7ec7fbcristy% G e t I m a g e E x t r e m a % 11653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 11663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 11673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 11683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 11693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 1170d42d995b9cb2a16e13221e665554417a5b7ec7fbcristy% GetImageExtrema() returns the extrema of one or more image channels. 11713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 1172d42d995b9cb2a16e13221e665554417a5b7ec7fbcristy% The format of the GetImageExtrema method is: 11733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 1174d42d995b9cb2a16e13221e665554417a5b7ec7fbcristy% MagickBooleanType GetImageExtrema(const Image *image,size_t *minima, 1175d42d995b9cb2a16e13221e665554417a5b7ec7fbcristy% size_t *maxima,ExceptionInfo *exception) 11763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 11773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% A description of each parameter follows: 11783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 11793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o image: the image. 11803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 11813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o minima: the minimum value in the channel. 11823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 11833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o maxima: the maximum value in the channel. 11843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 11853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o exception: return any errors or warnings in this structure. 11863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 11873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/ 11883ed852eea50f9d4cd633efb8c2b054b8e33c253cristyMagickExport MagickBooleanType GetImageExtrema(const Image *image, 1189bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy size_t *minima,size_t *maxima,ExceptionInfo *exception) 11903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 11913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy double 11923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy max, 11933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy min; 11943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 11953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy MagickBooleanType 11963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy status; 11973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 11983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy assert(image != (Image *) NULL); 1199e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy assert(image->signature == MagickCoreSignature); 12003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (image->debug != MagickFalse) 12013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); 1202d42d995b9cb2a16e13221e665554417a5b7ec7fbcristy status=GetImageRange(image,&min,&max,exception); 1203bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy *minima=(size_t) ceil(min-0.5); 1204bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy *maxima=(size_t) floor(max+0.5); 12053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return(status); 12063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 12073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 12083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* 12093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 12103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 12113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 12123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 1213bd4a3c228c0e785517b8ab630b2cc6095373f710cristy% G e t I m a g e K u r t o s i s % 1214bd4a3c228c0e785517b8ab630b2cc6095373f710cristy% % 1215bd4a3c228c0e785517b8ab630b2cc6095373f710cristy% % 1216bd4a3c228c0e785517b8ab630b2cc6095373f710cristy% % 1217bd4a3c228c0e785517b8ab630b2cc6095373f710cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1218bd4a3c228c0e785517b8ab630b2cc6095373f710cristy% 1219bd4a3c228c0e785517b8ab630b2cc6095373f710cristy% GetImageKurtosis() returns the kurtosis and skewness of one or more image 1220bd4a3c228c0e785517b8ab630b2cc6095373f710cristy% channels. 1221bd4a3c228c0e785517b8ab630b2cc6095373f710cristy% 1222bd4a3c228c0e785517b8ab630b2cc6095373f710cristy% The format of the GetImageKurtosis method is: 1223bd4a3c228c0e785517b8ab630b2cc6095373f710cristy% 1224bd4a3c228c0e785517b8ab630b2cc6095373f710cristy% MagickBooleanType GetImageKurtosis(const Image *image,double *kurtosis, 1225bd4a3c228c0e785517b8ab630b2cc6095373f710cristy% double *skewness,ExceptionInfo *exception) 1226bd4a3c228c0e785517b8ab630b2cc6095373f710cristy% 1227bd4a3c228c0e785517b8ab630b2cc6095373f710cristy% A description of each parameter follows: 1228bd4a3c228c0e785517b8ab630b2cc6095373f710cristy% 1229bd4a3c228c0e785517b8ab630b2cc6095373f710cristy% o image: the image. 1230bd4a3c228c0e785517b8ab630b2cc6095373f710cristy% 1231bd4a3c228c0e785517b8ab630b2cc6095373f710cristy% o kurtosis: the kurtosis of the channel. 1232bd4a3c228c0e785517b8ab630b2cc6095373f710cristy% 1233bd4a3c228c0e785517b8ab630b2cc6095373f710cristy% o skewness: the skewness of the channel. 1234bd4a3c228c0e785517b8ab630b2cc6095373f710cristy% 1235bd4a3c228c0e785517b8ab630b2cc6095373f710cristy% o exception: return any errors or warnings in this structure. 1236bd4a3c228c0e785517b8ab630b2cc6095373f710cristy% 1237bd4a3c228c0e785517b8ab630b2cc6095373f710cristy*/ 1238bd4a3c228c0e785517b8ab630b2cc6095373f710cristyMagickExport MagickBooleanType GetImageKurtosis(const Image *image, 1239bd4a3c228c0e785517b8ab630b2cc6095373f710cristy double *kurtosis,double *skewness,ExceptionInfo *exception) 1240bd4a3c228c0e785517b8ab630b2cc6095373f710cristy{ 1241bd4a3c228c0e785517b8ab630b2cc6095373f710cristy CacheView 1242bd4a3c228c0e785517b8ab630b2cc6095373f710cristy *image_view; 1243bd4a3c228c0e785517b8ab630b2cc6095373f710cristy 1244bd4a3c228c0e785517b8ab630b2cc6095373f710cristy double 1245bd4a3c228c0e785517b8ab630b2cc6095373f710cristy area, 1246bd4a3c228c0e785517b8ab630b2cc6095373f710cristy mean, 1247bd4a3c228c0e785517b8ab630b2cc6095373f710cristy standard_deviation, 1248bd4a3c228c0e785517b8ab630b2cc6095373f710cristy sum_squares, 1249bd4a3c228c0e785517b8ab630b2cc6095373f710cristy sum_cubes, 1250bd4a3c228c0e785517b8ab630b2cc6095373f710cristy sum_fourth_power; 1251bd4a3c228c0e785517b8ab630b2cc6095373f710cristy 1252bd4a3c228c0e785517b8ab630b2cc6095373f710cristy MagickBooleanType 1253bd4a3c228c0e785517b8ab630b2cc6095373f710cristy status; 1254bd4a3c228c0e785517b8ab630b2cc6095373f710cristy 1255bd4a3c228c0e785517b8ab630b2cc6095373f710cristy ssize_t 1256bd4a3c228c0e785517b8ab630b2cc6095373f710cristy y; 1257bd4a3c228c0e785517b8ab630b2cc6095373f710cristy 1258bd4a3c228c0e785517b8ab630b2cc6095373f710cristy assert(image != (Image *) NULL); 1259e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy assert(image->signature == MagickCoreSignature); 1260bd4a3c228c0e785517b8ab630b2cc6095373f710cristy if (image->debug != MagickFalse) 1261bd4a3c228c0e785517b8ab630b2cc6095373f710cristy (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); 1262bd4a3c228c0e785517b8ab630b2cc6095373f710cristy status=MagickTrue; 1263bd4a3c228c0e785517b8ab630b2cc6095373f710cristy *kurtosis=0.0; 1264bd4a3c228c0e785517b8ab630b2cc6095373f710cristy *skewness=0.0; 1265bd4a3c228c0e785517b8ab630b2cc6095373f710cristy area=0.0; 1266bd4a3c228c0e785517b8ab630b2cc6095373f710cristy mean=0.0; 1267bd4a3c228c0e785517b8ab630b2cc6095373f710cristy standard_deviation=0.0; 1268bd4a3c228c0e785517b8ab630b2cc6095373f710cristy sum_squares=0.0; 1269bd4a3c228c0e785517b8ab630b2cc6095373f710cristy sum_cubes=0.0; 1270bd4a3c228c0e785517b8ab630b2cc6095373f710cristy sum_fourth_power=0.0; 1271bd4a3c228c0e785517b8ab630b2cc6095373f710cristy image_view=AcquireVirtualCacheView(image,exception); 1272bd4a3c228c0e785517b8ab630b2cc6095373f710cristy#if defined(MAGICKCORE_OPENMP_SUPPORT) 1273bd4a3c228c0e785517b8ab630b2cc6095373f710cristy #pragma omp parallel for schedule(static,4) shared(status) \ 1274bd4a3c228c0e785517b8ab630b2cc6095373f710cristy magick_threads(image,image,image->rows,1) 1275bd4a3c228c0e785517b8ab630b2cc6095373f710cristy#endif 1276bd4a3c228c0e785517b8ab630b2cc6095373f710cristy for (y=0; y < (ssize_t) image->rows; y++) 1277bd4a3c228c0e785517b8ab630b2cc6095373f710cristy { 1278bd4a3c228c0e785517b8ab630b2cc6095373f710cristy register const Quantum 127905d2ff7ebf21f659f5b11e45afb294e152f4330cdirk *magick_restrict p; 1280bd4a3c228c0e785517b8ab630b2cc6095373f710cristy 1281bd4a3c228c0e785517b8ab630b2cc6095373f710cristy register ssize_t 1282bd4a3c228c0e785517b8ab630b2cc6095373f710cristy x; 1283bd4a3c228c0e785517b8ab630b2cc6095373f710cristy 1284bd4a3c228c0e785517b8ab630b2cc6095373f710cristy if (status == MagickFalse) 1285bd4a3c228c0e785517b8ab630b2cc6095373f710cristy continue; 1286bd4a3c228c0e785517b8ab630b2cc6095373f710cristy p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception); 1287bd4a3c228c0e785517b8ab630b2cc6095373f710cristy if (p == (const Quantum *) NULL) 1288bd4a3c228c0e785517b8ab630b2cc6095373f710cristy { 1289bd4a3c228c0e785517b8ab630b2cc6095373f710cristy status=MagickFalse; 1290bd4a3c228c0e785517b8ab630b2cc6095373f710cristy continue; 1291bd4a3c228c0e785517b8ab630b2cc6095373f710cristy } 1292bd4a3c228c0e785517b8ab630b2cc6095373f710cristy for (x=0; x < (ssize_t) image->columns; x++) 1293bd4a3c228c0e785517b8ab630b2cc6095373f710cristy { 1294bd4a3c228c0e785517b8ab630b2cc6095373f710cristy register ssize_t 1295bd4a3c228c0e785517b8ab630b2cc6095373f710cristy i; 1296bd4a3c228c0e785517b8ab630b2cc6095373f710cristy 1297bd4a3c228c0e785517b8ab630b2cc6095373f710cristy if (GetPixelReadMask(image,p) == 0) 1298bd4a3c228c0e785517b8ab630b2cc6095373f710cristy { 1299bd4a3c228c0e785517b8ab630b2cc6095373f710cristy p+=GetPixelChannels(image); 1300bd4a3c228c0e785517b8ab630b2cc6095373f710cristy continue; 1301bd4a3c228c0e785517b8ab630b2cc6095373f710cristy } 1302bd4a3c228c0e785517b8ab630b2cc6095373f710cristy for (i=0; i < (ssize_t) GetPixelChannels(image); i++) 1303bd4a3c228c0e785517b8ab630b2cc6095373f710cristy { 1304bd4a3c228c0e785517b8ab630b2cc6095373f710cristy PixelChannel channel=GetPixelChannelChannel(image,i); 1305bd4a3c228c0e785517b8ab630b2cc6095373f710cristy PixelTrait traits=GetPixelChannelTraits(image,channel); 1306bd4a3c228c0e785517b8ab630b2cc6095373f710cristy if (traits == UndefinedPixelTrait) 1307bd4a3c228c0e785517b8ab630b2cc6095373f710cristy continue; 1308bd4a3c228c0e785517b8ab630b2cc6095373f710cristy if ((traits & UpdatePixelTrait) == 0) 1309bd4a3c228c0e785517b8ab630b2cc6095373f710cristy continue; 1310bd4a3c228c0e785517b8ab630b2cc6095373f710cristy#if defined(MAGICKCORE_OPENMP_SUPPORT) 1311bd4a3c228c0e785517b8ab630b2cc6095373f710cristy #pragma omp critical (MagickCore_GetImageKurtosis) 1312bd4a3c228c0e785517b8ab630b2cc6095373f710cristy#endif 1313bd4a3c228c0e785517b8ab630b2cc6095373f710cristy { 1314bd4a3c228c0e785517b8ab630b2cc6095373f710cristy mean+=p[i]; 1315bd4a3c228c0e785517b8ab630b2cc6095373f710cristy sum_squares+=(double) p[i]*p[i]; 1316bd4a3c228c0e785517b8ab630b2cc6095373f710cristy sum_cubes+=(double) p[i]*p[i]*p[i]; 1317bd4a3c228c0e785517b8ab630b2cc6095373f710cristy sum_fourth_power+=(double) p[i]*p[i]*p[i]*p[i]; 1318bd4a3c228c0e785517b8ab630b2cc6095373f710cristy area++; 1319bd4a3c228c0e785517b8ab630b2cc6095373f710cristy } 1320bd4a3c228c0e785517b8ab630b2cc6095373f710cristy } 1321bd4a3c228c0e785517b8ab630b2cc6095373f710cristy p+=GetPixelChannels(image); 1322bd4a3c228c0e785517b8ab630b2cc6095373f710cristy } 1323bd4a3c228c0e785517b8ab630b2cc6095373f710cristy } 1324bd4a3c228c0e785517b8ab630b2cc6095373f710cristy image_view=DestroyCacheView(image_view); 1325bd4a3c228c0e785517b8ab630b2cc6095373f710cristy if (area != 0.0) 1326bd4a3c228c0e785517b8ab630b2cc6095373f710cristy { 1327bd4a3c228c0e785517b8ab630b2cc6095373f710cristy mean/=area; 1328bd4a3c228c0e785517b8ab630b2cc6095373f710cristy sum_squares/=area; 1329bd4a3c228c0e785517b8ab630b2cc6095373f710cristy sum_cubes/=area; 1330bd4a3c228c0e785517b8ab630b2cc6095373f710cristy sum_fourth_power/=area; 1331bd4a3c228c0e785517b8ab630b2cc6095373f710cristy } 1332bd4a3c228c0e785517b8ab630b2cc6095373f710cristy standard_deviation=sqrt(sum_squares-(mean*mean)); 1333bd4a3c228c0e785517b8ab630b2cc6095373f710cristy if (standard_deviation != 0.0) 1334bd4a3c228c0e785517b8ab630b2cc6095373f710cristy { 1335bd4a3c228c0e785517b8ab630b2cc6095373f710cristy *kurtosis=sum_fourth_power-4.0*mean*sum_cubes+6.0*mean*mean*sum_squares- 1336bd4a3c228c0e785517b8ab630b2cc6095373f710cristy 3.0*mean*mean*mean*mean; 1337bd4a3c228c0e785517b8ab630b2cc6095373f710cristy *kurtosis/=standard_deviation*standard_deviation*standard_deviation* 1338bd4a3c228c0e785517b8ab630b2cc6095373f710cristy standard_deviation; 1339bd4a3c228c0e785517b8ab630b2cc6095373f710cristy *kurtosis-=3.0; 1340bd4a3c228c0e785517b8ab630b2cc6095373f710cristy *skewness=sum_cubes-3.0*mean*sum_squares+2.0*mean*mean*mean; 1341bd4a3c228c0e785517b8ab630b2cc6095373f710cristy *skewness/=standard_deviation*standard_deviation*standard_deviation; 1342bd4a3c228c0e785517b8ab630b2cc6095373f710cristy } 1343bd4a3c228c0e785517b8ab630b2cc6095373f710cristy return(status); 1344bd4a3c228c0e785517b8ab630b2cc6095373f710cristy} 1345bd4a3c228c0e785517b8ab630b2cc6095373f710cristy 1346bd4a3c228c0e785517b8ab630b2cc6095373f710cristy/* 1347bd4a3c228c0e785517b8ab630b2cc6095373f710cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1348bd4a3c228c0e785517b8ab630b2cc6095373f710cristy% % 1349bd4a3c228c0e785517b8ab630b2cc6095373f710cristy% % 1350bd4a3c228c0e785517b8ab630b2cc6095373f710cristy% % 1351d42d995b9cb2a16e13221e665554417a5b7ec7fbcristy% G e t I m a g e M e a n % 13523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 13533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 13543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 13553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 13563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 13575048d30ffd6670a4b4c9986bbcb46b228afdd884cristy% GetImageMean() returns the mean and standard deviation of one or more image 13585048d30ffd6670a4b4c9986bbcb46b228afdd884cristy% channels. 13593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 1360d42d995b9cb2a16e13221e665554417a5b7ec7fbcristy% The format of the GetImageMean method is: 13613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 1362d42d995b9cb2a16e13221e665554417a5b7ec7fbcristy% MagickBooleanType GetImageMean(const Image *image,double *mean, 1363d42d995b9cb2a16e13221e665554417a5b7ec7fbcristy% double *standard_deviation,ExceptionInfo *exception) 13643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 13653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% A description of each parameter follows: 13663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 13673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o image: the image. 13683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 13693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o mean: the average value in the channel. 13703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 13713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o standard_deviation: the standard deviation of the channel. 13723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 13733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o exception: return any errors or warnings in this structure. 13743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 13753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/ 13763ed852eea50f9d4cd633efb8c2b054b8e33c253cristyMagickExport MagickBooleanType GetImageMean(const Image *image,double *mean, 13773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy double *standard_deviation,ExceptionInfo *exception) 13783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 13795048d30ffd6670a4b4c9986bbcb46b228afdd884cristy double 13805048d30ffd6670a4b4c9986bbcb46b228afdd884cristy area; 13815048d30ffd6670a4b4c9986bbcb46b228afdd884cristy 1382fd9dcd4a312944c590a433c5d519146364fa6932cristy ChannelStatistics 1383fd9dcd4a312944c590a433c5d519146364fa6932cristy *channel_statistics; 13843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 138594a757875f6ef9dcbbc4f97bbca32b736d28de4ecristy register ssize_t 138694a757875f6ef9dcbbc4f97bbca32b736d28de4ecristy i; 138794a757875f6ef9dcbbc4f97bbca32b736d28de4ecristy 13883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy assert(image != (Image *) NULL); 1389e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy assert(image->signature == MagickCoreSignature); 13903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (image->debug != MagickFalse) 13913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); 1392d42d995b9cb2a16e13221e665554417a5b7ec7fbcristy channel_statistics=GetImageStatistics(image,exception); 1393fd9dcd4a312944c590a433c5d519146364fa6932cristy if (channel_statistics == (ChannelStatistics *) NULL) 1394fd9dcd4a312944c590a433c5d519146364fa6932cristy return(MagickFalse); 13955048d30ffd6670a4b4c9986bbcb46b228afdd884cristy area=0.0; 13965f95f4f77efc46ff53593d750491c8f60698c983cristy channel_statistics[CompositePixelChannel].mean=0.0; 13975f95f4f77efc46ff53593d750491c8f60698c983cristy channel_statistics[CompositePixelChannel].standard_deviation=0.0; 139894a757875f6ef9dcbbc4f97bbca32b736d28de4ecristy for (i=0; i < (ssize_t) GetPixelChannels(image); i++) 139994a757875f6ef9dcbbc4f97bbca32b736d28de4ecristy { 14005a23c55ddcfdf6ae717dd42d8a1c1a2ff8c6305fcristy PixelChannel channel=GetPixelChannelChannel(image,i); 14015a23c55ddcfdf6ae717dd42d8a1c1a2ff8c6305fcristy PixelTrait traits=GetPixelChannelTraits(image,channel); 140294a757875f6ef9dcbbc4f97bbca32b736d28de4ecristy if (traits == UndefinedPixelTrait) 140394a757875f6ef9dcbbc4f97bbca32b736d28de4ecristy continue; 140494a757875f6ef9dcbbc4f97bbca32b736d28de4ecristy if ((traits & UpdatePixelTrait) == 0) 140594a757875f6ef9dcbbc4f97bbca32b736d28de4ecristy continue; 14065f95f4f77efc46ff53593d750491c8f60698c983cristy channel_statistics[CompositePixelChannel].mean+=channel_statistics[i].mean; 14075f95f4f77efc46ff53593d750491c8f60698c983cristy channel_statistics[CompositePixelChannel].standard_deviation+= 140894a757875f6ef9dcbbc4f97bbca32b736d28de4ecristy channel_statistics[i].variance-channel_statistics[i].mean* 140994a757875f6ef9dcbbc4f97bbca32b736d28de4ecristy channel_statistics[i].mean; 141094a757875f6ef9dcbbc4f97bbca32b736d28de4ecristy area++; 141194a757875f6ef9dcbbc4f97bbca32b736d28de4ecristy } 141244706661c10e56ccd366f5d48b28f3103ff21e5ecristy if (area > MagickEpsilon) 141344706661c10e56ccd366f5d48b28f3103ff21e5ecristy { 141444706661c10e56ccd366f5d48b28f3103ff21e5ecristy channel_statistics[CompositePixelChannel].mean/=area; 141544706661c10e56ccd366f5d48b28f3103ff21e5ecristy channel_statistics[CompositePixelChannel].standard_deviation= 141644706661c10e56ccd366f5d48b28f3103ff21e5ecristy sqrt(channel_statistics[CompositePixelChannel].standard_deviation/area); 141744706661c10e56ccd366f5d48b28f3103ff21e5ecristy } 14185f95f4f77efc46ff53593d750491c8f60698c983cristy *mean=channel_statistics[CompositePixelChannel].mean; 1419e2a912b6c9086c98ec838baa0824cd8deca55538cristy *standard_deviation= 1420e2a912b6c9086c98ec838baa0824cd8deca55538cristy channel_statistics[CompositePixelChannel].standard_deviation; 1421fd9dcd4a312944c590a433c5d519146364fa6932cristy channel_statistics=(ChannelStatistics *) RelinquishMagickMemory( 1422fd9dcd4a312944c590a433c5d519146364fa6932cristy channel_statistics); 1423fd9dcd4a312944c590a433c5d519146364fa6932cristy return(MagickTrue); 14243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 14253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 14263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* 14273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 14283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 14293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 14303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 1431bd4a3c228c0e785517b8ab630b2cc6095373f710cristy% G e t I m a g e M o m e n t s % 14323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 14333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 14343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 14353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 14363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 14376b3de2b7931481269d953d26f5de67471a8bf6f3cristy% GetImageMoments() returns the normalized moments of one or more image 14386b3de2b7931481269d953d26f5de67471a8bf6f3cristy% channels. 14393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 1440bd4a3c228c0e785517b8ab630b2cc6095373f710cristy% The format of the GetImageMoments method is: 14413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 1442bd4a3c228c0e785517b8ab630b2cc6095373f710cristy% ChannelMoments *GetImageMoments(const Image *image, 1443bd4a3c228c0e785517b8ab630b2cc6095373f710cristy% ExceptionInfo *exception) 14443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 14453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% A description of each parameter follows: 14463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 14473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o image: the image. 14483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 14493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o exception: return any errors or warnings in this structure. 14503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 14513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/ 1452e22513c47799a2fc63e145f93c6ee03269767ba0cristy 1453e22513c47799a2fc63e145f93c6ee03269767ba0cristystatic size_t GetImageChannels(const Image *image) 1454e22513c47799a2fc63e145f93c6ee03269767ba0cristy{ 1455e22513c47799a2fc63e145f93c6ee03269767ba0cristy register ssize_t 1456e22513c47799a2fc63e145f93c6ee03269767ba0cristy i; 1457e22513c47799a2fc63e145f93c6ee03269767ba0cristy 1458e22513c47799a2fc63e145f93c6ee03269767ba0cristy size_t 1459e22513c47799a2fc63e145f93c6ee03269767ba0cristy channels; 1460e22513c47799a2fc63e145f93c6ee03269767ba0cristy 1461e22513c47799a2fc63e145f93c6ee03269767ba0cristy channels=0; 1462e22513c47799a2fc63e145f93c6ee03269767ba0cristy for (i=0; i < (ssize_t) GetPixelChannels(image); i++) 1463e22513c47799a2fc63e145f93c6ee03269767ba0cristy { 1464e22513c47799a2fc63e145f93c6ee03269767ba0cristy PixelChannel channel=GetPixelChannelChannel(image,i); 1465e22513c47799a2fc63e145f93c6ee03269767ba0cristy PixelTrait traits=GetPixelChannelTraits(image,channel); 1466e22513c47799a2fc63e145f93c6ee03269767ba0cristy if ((traits & UpdatePixelTrait) != 0) 1467e22513c47799a2fc63e145f93c6ee03269767ba0cristy channels++; 1468e22513c47799a2fc63e145f93c6ee03269767ba0cristy } 146981c3360b2dfd109013aa2116eeb3a3caa29dd362cristy return((size_t) (channels == 0 ? 1 : channels)); 1470e22513c47799a2fc63e145f93c6ee03269767ba0cristy} 1471e22513c47799a2fc63e145f93c6ee03269767ba0cristy 1472bd4a3c228c0e785517b8ab630b2cc6095373f710cristyMagickExport ChannelMoments *GetImageMoments(const Image *image, 1473bd4a3c228c0e785517b8ab630b2cc6095373f710cristy ExceptionInfo *exception) 14743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 1475bd4a3c228c0e785517b8ab630b2cc6095373f710cristy#define MaxNumberImageMoments 8 1476bd4a3c228c0e785517b8ab630b2cc6095373f710cristy 147794a757875f6ef9dcbbc4f97bbca32b736d28de4ecristy CacheView 147894a757875f6ef9dcbbc4f97bbca32b736d28de4ecristy *image_view; 147994a757875f6ef9dcbbc4f97bbca32b736d28de4ecristy 1480bd4a3c228c0e785517b8ab630b2cc6095373f710cristy ChannelMoments 1481bd4a3c228c0e785517b8ab630b2cc6095373f710cristy *channel_moments; 14823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 14832a22aaab1509397c26047182cc73275f1f251075cristy double 14842a22aaab1509397c26047182cc73275f1f251075cristy M00[MaxPixelChannels+1], 14852a22aaab1509397c26047182cc73275f1f251075cristy M01[MaxPixelChannels+1], 14862a22aaab1509397c26047182cc73275f1f251075cristy M02[MaxPixelChannels+1], 14872a22aaab1509397c26047182cc73275f1f251075cristy M03[MaxPixelChannels+1], 14882a22aaab1509397c26047182cc73275f1f251075cristy M10[MaxPixelChannels+1], 14892a22aaab1509397c26047182cc73275f1f251075cristy M11[MaxPixelChannels+1], 14902a22aaab1509397c26047182cc73275f1f251075cristy M12[MaxPixelChannels+1], 14912a22aaab1509397c26047182cc73275f1f251075cristy M20[MaxPixelChannels+1], 14922a22aaab1509397c26047182cc73275f1f251075cristy M21[MaxPixelChannels+1], 14932a22aaab1509397c26047182cc73275f1f251075cristy M22[MaxPixelChannels+1], 1494cb9af4ac6134e7e15e7d344489e9e0f634e1b4c1cristy M30[MaxPixelChannels+1]; 14952a22aaab1509397c26047182cc73275f1f251075cristy 14962a22aaab1509397c26047182cc73275f1f251075cristy PointInfo 14972a22aaab1509397c26047182cc73275f1f251075cristy centroid[MaxPixelChannels+1]; 1498a9ec2bb46f44af91aac5091a183a3a874d9d480edirk 1499bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy ssize_t 15002a22aaab1509397c26047182cc73275f1f251075cristy channel, 15013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy y; 15023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 15033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy assert(image != (Image *) NULL); 1504e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy assert(image->signature == MagickCoreSignature); 15053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (image->debug != MagickFalse) 15063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); 15072a22aaab1509397c26047182cc73275f1f251075cristy channel_moments=(ChannelMoments *) AcquireQuantumMemory(MaxPixelChannels+1, 1508bd4a3c228c0e785517b8ab630b2cc6095373f710cristy sizeof(*channel_moments)); 1509bd4a3c228c0e785517b8ab630b2cc6095373f710cristy if (channel_moments == (ChannelMoments *) NULL) 1510bd4a3c228c0e785517b8ab630b2cc6095373f710cristy return(channel_moments); 15112a22aaab1509397c26047182cc73275f1f251075cristy (void) ResetMagickMemory(channel_moments,0,(MaxPixelChannels+1)* 15122a22aaab1509397c26047182cc73275f1f251075cristy sizeof(*channel_moments)); 15132a22aaab1509397c26047182cc73275f1f251075cristy (void) ResetMagickMemory(centroid,0,sizeof(centroid)); 15142a22aaab1509397c26047182cc73275f1f251075cristy (void) ResetMagickMemory(M00,0,sizeof(M00)); 15152a22aaab1509397c26047182cc73275f1f251075cristy (void) ResetMagickMemory(M01,0,sizeof(M01)); 15162a22aaab1509397c26047182cc73275f1f251075cristy (void) ResetMagickMemory(M02,0,sizeof(M02)); 15172a22aaab1509397c26047182cc73275f1f251075cristy (void) ResetMagickMemory(M03,0,sizeof(M03)); 15182a22aaab1509397c26047182cc73275f1f251075cristy (void) ResetMagickMemory(M10,0,sizeof(M10)); 15192a22aaab1509397c26047182cc73275f1f251075cristy (void) ResetMagickMemory(M11,0,sizeof(M11)); 15202a22aaab1509397c26047182cc73275f1f251075cristy (void) ResetMagickMemory(M12,0,sizeof(M12)); 15212a22aaab1509397c26047182cc73275f1f251075cristy (void) ResetMagickMemory(M20,0,sizeof(M20)); 15222a22aaab1509397c26047182cc73275f1f251075cristy (void) ResetMagickMemory(M21,0,sizeof(M21)); 15232a22aaab1509397c26047182cc73275f1f251075cristy (void) ResetMagickMemory(M22,0,sizeof(M22)); 15242a22aaab1509397c26047182cc73275f1f251075cristy (void) ResetMagickMemory(M30,0,sizeof(M30)); 152546ff2676b1044ea4101ac7a59b83289cd8f6cfdacristy image_view=AcquireVirtualCacheView(image,exception); 1526bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy for (y=0; y < (ssize_t) image->rows; y++) 15273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 15284c08aed51c5899665ade97263692328eea4af106cristy register const Quantum 152905d2ff7ebf21f659f5b11e45afb294e152f4330cdirk *magick_restrict p; 15303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 1531bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy register ssize_t 15323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy x; 15333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 15342a22aaab1509397c26047182cc73275f1f251075cristy /* 15352a22aaab1509397c26047182cc73275f1f251075cristy Compute center of mass (centroid). 15362a22aaab1509397c26047182cc73275f1f251075cristy */ 153794a757875f6ef9dcbbc4f97bbca32b736d28de4ecristy p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception); 15384c08aed51c5899665ade97263692328eea4af106cristy if (p == (const Quantum *) NULL) 15392a22aaab1509397c26047182cc73275f1f251075cristy break; 1540bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy for (x=0; x < (ssize_t) image->columns; x++) 15413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 154294a757875f6ef9dcbbc4f97bbca32b736d28de4ecristy register ssize_t 154394a757875f6ef9dcbbc4f97bbca32b736d28de4ecristy i; 154494a757875f6ef9dcbbc4f97bbca32b736d28de4ecristy 1545883fde11debec15cedb05dc5d7228d8588066bc0cristy if (GetPixelReadMask(image,p) == 0) 15466d94a308cc4b42b09f5020acce05d779e24faa47cristy { 15476d94a308cc4b42b09f5020acce05d779e24faa47cristy p+=GetPixelChannels(image); 15486d94a308cc4b42b09f5020acce05d779e24faa47cristy continue; 15496d94a308cc4b42b09f5020acce05d779e24faa47cristy } 155094a757875f6ef9dcbbc4f97bbca32b736d28de4ecristy for (i=0; i < (ssize_t) GetPixelChannels(image); i++) 155194a757875f6ef9dcbbc4f97bbca32b736d28de4ecristy { 15525a23c55ddcfdf6ae717dd42d8a1c1a2ff8c6305fcristy PixelChannel channel=GetPixelChannelChannel(image,i); 15535a23c55ddcfdf6ae717dd42d8a1c1a2ff8c6305fcristy PixelTrait traits=GetPixelChannelTraits(image,channel); 155494a757875f6ef9dcbbc4f97bbca32b736d28de4ecristy if (traits == UndefinedPixelTrait) 155594a757875f6ef9dcbbc4f97bbca32b736d28de4ecristy continue; 15566d94a308cc4b42b09f5020acce05d779e24faa47cristy if ((traits & UpdatePixelTrait) == 0) 155794a757875f6ef9dcbbc4f97bbca32b736d28de4ecristy continue; 1558cb9af4ac6134e7e15e7d344489e9e0f634e1b4c1cristy M00[channel]+=QuantumScale*p[i]; 1559b5a738f267f28d95bf0103934aa48a50f2d502b9cristy M00[MaxPixelChannels]+=QuantumScale*p[i]; 1560cb9af4ac6134e7e15e7d344489e9e0f634e1b4c1cristy M10[channel]+=x*QuantumScale*p[i]; 1561cb28e4323ca26dd27838e97fb6fe1ee678ce33d9cristy M10[MaxPixelChannels]+=x*QuantumScale*p[i]; 1562cb9af4ac6134e7e15e7d344489e9e0f634e1b4c1cristy M01[channel]+=y*QuantumScale*p[i]; 1563cb28e4323ca26dd27838e97fb6fe1ee678ce33d9cristy M01[MaxPixelChannels]+=y*QuantumScale*p[i]; 15642a22aaab1509397c26047182cc73275f1f251075cristy } 15652a22aaab1509397c26047182cc73275f1f251075cristy p+=GetPixelChannels(image); 15662a22aaab1509397c26047182cc73275f1f251075cristy } 15672a22aaab1509397c26047182cc73275f1f251075cristy } 15682a22aaab1509397c26047182cc73275f1f251075cristy for (channel=0; channel <= MaxPixelChannels; channel++) 15692a22aaab1509397c26047182cc73275f1f251075cristy { 15702a22aaab1509397c26047182cc73275f1f251075cristy /* 15712a22aaab1509397c26047182cc73275f1f251075cristy Compute center of mass (centroid). 15722a22aaab1509397c26047182cc73275f1f251075cristy */ 15730633a1f35940363594ecb272bb113e045fd65f93cristy if (M00[channel] < MagickEpsilon) 15740633a1f35940363594ecb272bb113e045fd65f93cristy { 15750633a1f35940363594ecb272bb113e045fd65f93cristy M00[channel]+=MagickEpsilon; 157681c3360b2dfd109013aa2116eeb3a3caa29dd362cristy centroid[channel].x=(double) image->columns/2.0; 157781c3360b2dfd109013aa2116eeb3a3caa29dd362cristy centroid[channel].y=(double) image->rows/2.0; 15780633a1f35940363594ecb272bb113e045fd65f93cristy continue; 15790633a1f35940363594ecb272bb113e045fd65f93cristy } 158012cdaaec0ce96a51b80c1c5ceea1a4ea7c4574f7cristy M00[channel]+=MagickEpsilon; 15812a22aaab1509397c26047182cc73275f1f251075cristy centroid[channel].x=M10[channel]/M00[channel]; 15822a22aaab1509397c26047182cc73275f1f251075cristy centroid[channel].y=M01[channel]/M00[channel]; 15832a22aaab1509397c26047182cc73275f1f251075cristy } 15842a22aaab1509397c26047182cc73275f1f251075cristy for (y=0; y < (ssize_t) image->rows; y++) 15852a22aaab1509397c26047182cc73275f1f251075cristy { 15862a22aaab1509397c26047182cc73275f1f251075cristy register const Quantum 158705d2ff7ebf21f659f5b11e45afb294e152f4330cdirk *magick_restrict p; 15882a22aaab1509397c26047182cc73275f1f251075cristy 15892a22aaab1509397c26047182cc73275f1f251075cristy register ssize_t 15902a22aaab1509397c26047182cc73275f1f251075cristy x; 15912a22aaab1509397c26047182cc73275f1f251075cristy 15922a22aaab1509397c26047182cc73275f1f251075cristy /* 15932a22aaab1509397c26047182cc73275f1f251075cristy Compute the image moments. 15942a22aaab1509397c26047182cc73275f1f251075cristy */ 15952a22aaab1509397c26047182cc73275f1f251075cristy p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception); 15962a22aaab1509397c26047182cc73275f1f251075cristy if (p == (const Quantum *) NULL) 15972a22aaab1509397c26047182cc73275f1f251075cristy break; 15982a22aaab1509397c26047182cc73275f1f251075cristy for (x=0; x < (ssize_t) image->columns; x++) 15992a22aaab1509397c26047182cc73275f1f251075cristy { 16002a22aaab1509397c26047182cc73275f1f251075cristy register ssize_t 16012a22aaab1509397c26047182cc73275f1f251075cristy i; 16022a22aaab1509397c26047182cc73275f1f251075cristy 16032a22aaab1509397c26047182cc73275f1f251075cristy if (GetPixelReadMask(image,p) == 0) 16043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 16052a22aaab1509397c26047182cc73275f1f251075cristy p+=GetPixelChannels(image); 16062a22aaab1509397c26047182cc73275f1f251075cristy continue; 16073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 16082a22aaab1509397c26047182cc73275f1f251075cristy for (i=0; i < (ssize_t) GetPixelChannels(image); i++) 16092a22aaab1509397c26047182cc73275f1f251075cristy { 16102a22aaab1509397c26047182cc73275f1f251075cristy PixelChannel channel=GetPixelChannelChannel(image,i); 16112a22aaab1509397c26047182cc73275f1f251075cristy PixelTrait traits=GetPixelChannelTraits(image,channel); 16122a22aaab1509397c26047182cc73275f1f251075cristy if (traits == UndefinedPixelTrait) 16132a22aaab1509397c26047182cc73275f1f251075cristy continue; 16142a22aaab1509397c26047182cc73275f1f251075cristy if ((traits & UpdatePixelTrait) == 0) 16152a22aaab1509397c26047182cc73275f1f251075cristy continue; 161620b0c74e0979efb79370e5e9bd6047996ffa7b43cristy M11[channel]+=(x-centroid[channel].x)*(y-centroid[channel].y)* 1617cb9af4ac6134e7e15e7d344489e9e0f634e1b4c1cristy QuantumScale*p[i]; 1618b5a738f267f28d95bf0103934aa48a50f2d502b9cristy M11[MaxPixelChannels]+=(x-centroid[channel].x)*(y-centroid[channel].y)* 1619b5a738f267f28d95bf0103934aa48a50f2d502b9cristy QuantumScale*p[i]; 162020b0c74e0979efb79370e5e9bd6047996ffa7b43cristy M20[channel]+=(x-centroid[channel].x)*(x-centroid[channel].x)* 1621cb9af4ac6134e7e15e7d344489e9e0f634e1b4c1cristy QuantumScale*p[i]; 1622b5a738f267f28d95bf0103934aa48a50f2d502b9cristy M20[MaxPixelChannels]+=(x-centroid[channel].x)*(x-centroid[channel].x)* 1623b5a738f267f28d95bf0103934aa48a50f2d502b9cristy QuantumScale*p[i]; 162420b0c74e0979efb79370e5e9bd6047996ffa7b43cristy M02[channel]+=(y-centroid[channel].y)*(y-centroid[channel].y)* 1625cb9af4ac6134e7e15e7d344489e9e0f634e1b4c1cristy QuantumScale*p[i]; 1626b5a738f267f28d95bf0103934aa48a50f2d502b9cristy M02[MaxPixelChannels]+=(y-centroid[channel].y)*(y-centroid[channel].y)* 1627b5a738f267f28d95bf0103934aa48a50f2d502b9cristy QuantumScale*p[i]; 16282a22aaab1509397c26047182cc73275f1f251075cristy M21[channel]+=(x-centroid[channel].x)*(x-centroid[channel].x)* 1629cb9af4ac6134e7e15e7d344489e9e0f634e1b4c1cristy (y-centroid[channel].y)*QuantumScale*p[i]; 1630b5a738f267f28d95bf0103934aa48a50f2d502b9cristy M21[MaxPixelChannels]+=(x-centroid[channel].x)*(x-centroid[channel].x)* 1631b5a738f267f28d95bf0103934aa48a50f2d502b9cristy (y-centroid[channel].y)*QuantumScale*p[i]; 16322a22aaab1509397c26047182cc73275f1f251075cristy M12[channel]+=(x-centroid[channel].x)*(y-centroid[channel].y)* 1633cb9af4ac6134e7e15e7d344489e9e0f634e1b4c1cristy (y-centroid[channel].y)*QuantumScale*p[i]; 1634b5a738f267f28d95bf0103934aa48a50f2d502b9cristy M12[MaxPixelChannels]+=(x-centroid[channel].x)*(y-centroid[channel].y)* 1635b5a738f267f28d95bf0103934aa48a50f2d502b9cristy (y-centroid[channel].y)*QuantumScale*p[i]; 16362a22aaab1509397c26047182cc73275f1f251075cristy M22[channel]+=(x-centroid[channel].x)*(x-centroid[channel].x)* 1637cb9af4ac6134e7e15e7d344489e9e0f634e1b4c1cristy (y-centroid[channel].y)*(y-centroid[channel].y)*QuantumScale*p[i]; 1638b5a738f267f28d95bf0103934aa48a50f2d502b9cristy M22[MaxPixelChannels]+=(x-centroid[channel].x)*(x-centroid[channel].x)* 1639b5a738f267f28d95bf0103934aa48a50f2d502b9cristy (y-centroid[channel].y)*(y-centroid[channel].y)*QuantumScale*p[i]; 16402a22aaab1509397c26047182cc73275f1f251075cristy M30[channel]+=(x-centroid[channel].x)*(x-centroid[channel].x)* 1641cb9af4ac6134e7e15e7d344489e9e0f634e1b4c1cristy (x-centroid[channel].x)*QuantumScale*p[i]; 1642b5a738f267f28d95bf0103934aa48a50f2d502b9cristy M30[MaxPixelChannels]+=(x-centroid[channel].x)*(x-centroid[channel].x)* 1643b5a738f267f28d95bf0103934aa48a50f2d502b9cristy (x-centroid[channel].x)*QuantumScale*p[i]; 16442a22aaab1509397c26047182cc73275f1f251075cristy M03[channel]+=(y-centroid[channel].y)*(y-centroid[channel].y)* 1645cb9af4ac6134e7e15e7d344489e9e0f634e1b4c1cristy (y-centroid[channel].y)*QuantumScale*p[i]; 1646b5a738f267f28d95bf0103934aa48a50f2d502b9cristy M03[MaxPixelChannels]+=(y-centroid[channel].y)*(y-centroid[channel].y)* 1647b5a738f267f28d95bf0103934aa48a50f2d502b9cristy (y-centroid[channel].y)*QuantumScale*p[i]; 164894a757875f6ef9dcbbc4f97bbca32b736d28de4ecristy } 1649ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy p+=GetPixelChannels(image); 16503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 16513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 1652e22513c47799a2fc63e145f93c6ee03269767ba0cristy M00[MaxPixelChannels]/=GetImageChannels(image); 1653e22513c47799a2fc63e145f93c6ee03269767ba0cristy M01[MaxPixelChannels]/=GetImageChannels(image); 1654e22513c47799a2fc63e145f93c6ee03269767ba0cristy M02[MaxPixelChannels]/=GetImageChannels(image); 1655e22513c47799a2fc63e145f93c6ee03269767ba0cristy M03[MaxPixelChannels]/=GetImageChannels(image); 1656e22513c47799a2fc63e145f93c6ee03269767ba0cristy M10[MaxPixelChannels]/=GetImageChannels(image); 1657e22513c47799a2fc63e145f93c6ee03269767ba0cristy M11[MaxPixelChannels]/=GetImageChannels(image); 1658e22513c47799a2fc63e145f93c6ee03269767ba0cristy M12[MaxPixelChannels]/=GetImageChannels(image); 1659e22513c47799a2fc63e145f93c6ee03269767ba0cristy M20[MaxPixelChannels]/=GetImageChannels(image); 1660e22513c47799a2fc63e145f93c6ee03269767ba0cristy M21[MaxPixelChannels]/=GetImageChannels(image); 1661e22513c47799a2fc63e145f93c6ee03269767ba0cristy M22[MaxPixelChannels]/=GetImageChannels(image); 1662e22513c47799a2fc63e145f93c6ee03269767ba0cristy M30[MaxPixelChannels]/=GetImageChannels(image); 16632a22aaab1509397c26047182cc73275f1f251075cristy for (channel=0; channel <= MaxPixelChannels; channel++) 16642a22aaab1509397c26047182cc73275f1f251075cristy { 16652a22aaab1509397c26047182cc73275f1f251075cristy /* 1666a520f2362aafd6cb7ae888ff3559b09ac20b7924cristy Compute elliptical angle, major and minor axes, eccentricity, & intensity. 1667a520f2362aafd6cb7ae888ff3559b09ac20b7924cristy */ 1668a520f2362aafd6cb7ae888ff3559b09ac20b7924cristy channel_moments[channel].centroid=centroid[channel]; 1669a520f2362aafd6cb7ae888ff3559b09ac20b7924cristy channel_moments[channel].ellipse_axis.x=sqrt((2.0/M00[channel])* 1670a520f2362aafd6cb7ae888ff3559b09ac20b7924cristy ((M20[channel]+M02[channel])+sqrt(4.0*M11[channel]*M11[channel]+ 1671a520f2362aafd6cb7ae888ff3559b09ac20b7924cristy (M20[channel]-M02[channel])*(M20[channel]-M02[channel])))); 1672a520f2362aafd6cb7ae888ff3559b09ac20b7924cristy channel_moments[channel].ellipse_axis.y=sqrt((2.0/M00[channel])* 1673a520f2362aafd6cb7ae888ff3559b09ac20b7924cristy ((M20[channel]+M02[channel])-sqrt(4.0*M11[channel]*M11[channel]+ 1674a520f2362aafd6cb7ae888ff3559b09ac20b7924cristy (M20[channel]-M02[channel])*(M20[channel]-M02[channel])))); 1675a520f2362aafd6cb7ae888ff3559b09ac20b7924cristy channel_moments[channel].ellipse_angle=RadiansToDegrees(0.5*atan(2.0* 1676c17edf220b9be5b9d35d28687cdba90a641b0edfcristy M11[channel]/(M20[channel]-M02[channel]+MagickEpsilon))); 1677a520f2362aafd6cb7ae888ff3559b09ac20b7924cristy channel_moments[channel].ellipse_eccentricity=sqrt(1.0-( 1678a520f2362aafd6cb7ae888ff3559b09ac20b7924cristy channel_moments[channel].ellipse_axis.y/ 1679c17edf220b9be5b9d35d28687cdba90a641b0edfcristy (channel_moments[channel].ellipse_axis.x+MagickEpsilon))); 16800c0bae941a2dc028b90b78c9f7086a93ab6417becristy channel_moments[channel].ellipse_intensity=M00[channel]/ 1681794f200f5b83a30d81027733122ed5f3506d3e03cristy (MagickPI*channel_moments[channel].ellipse_axis.x* 1682c17edf220b9be5b9d35d28687cdba90a641b0edfcristy channel_moments[channel].ellipse_axis.y+MagickEpsilon); 1683a520f2362aafd6cb7ae888ff3559b09ac20b7924cristy } 1684a520f2362aafd6cb7ae888ff3559b09ac20b7924cristy for (channel=0; channel <= MaxPixelChannels; channel++) 1685a520f2362aafd6cb7ae888ff3559b09ac20b7924cristy { 1686a520f2362aafd6cb7ae888ff3559b09ac20b7924cristy /* 16872a22aaab1509397c26047182cc73275f1f251075cristy Normalize image moments. 16882a22aaab1509397c26047182cc73275f1f251075cristy */ 16892b8f9ffb1ee6c2011758352e89efcbf640112873cristy M10[channel]=0.0; 16902b8f9ffb1ee6c2011758352e89efcbf640112873cristy M01[channel]=0.0; 1691b51417b1df71e6b1d82bb44e01db9ffdb0719709cristy M11[channel]/=pow(M00[channel],1.0+(1.0+1.0)/2.0); 1692b51417b1df71e6b1d82bb44e01db9ffdb0719709cristy M20[channel]/=pow(M00[channel],1.0+(2.0+0.0)/2.0); 1693b51417b1df71e6b1d82bb44e01db9ffdb0719709cristy M02[channel]/=pow(M00[channel],1.0+(0.0+2.0)/2.0); 1694b51417b1df71e6b1d82bb44e01db9ffdb0719709cristy M21[channel]/=pow(M00[channel],1.0+(2.0+1.0)/2.0); 1695b51417b1df71e6b1d82bb44e01db9ffdb0719709cristy M12[channel]/=pow(M00[channel],1.0+(1.0+2.0)/2.0); 1696b51417b1df71e6b1d82bb44e01db9ffdb0719709cristy M22[channel]/=pow(M00[channel],1.0+(2.0+2.0)/2.0); 1697b51417b1df71e6b1d82bb44e01db9ffdb0719709cristy M30[channel]/=pow(M00[channel],1.0+(3.0+0.0)/2.0); 1698b51417b1df71e6b1d82bb44e01db9ffdb0719709cristy M03[channel]/=pow(M00[channel],1.0+(0.0+3.0)/2.0); 16992b8f9ffb1ee6c2011758352e89efcbf640112873cristy M00[channel]=1.0; 17002a22aaab1509397c26047182cc73275f1f251075cristy } 170194a757875f6ef9dcbbc4f97bbca32b736d28de4ecristy image_view=DestroyCacheView(image_view); 17022a22aaab1509397c26047182cc73275f1f251075cristy for (channel=0; channel <= MaxPixelChannels; channel++) 17032a22aaab1509397c26047182cc73275f1f251075cristy { 17042a22aaab1509397c26047182cc73275f1f251075cristy /* 17052a22aaab1509397c26047182cc73275f1f251075cristy Compute Hu invariant moments. 17062a22aaab1509397c26047182cc73275f1f251075cristy */ 170757f71289ef12fb275c908972156e7e397d9e07bbcristy channel_moments[channel].invariant[0]=M20[channel]+M02[channel]; 170857f71289ef12fb275c908972156e7e397d9e07bbcristy channel_moments[channel].invariant[1]=(M20[channel]-M02[channel])* 17092a22aaab1509397c26047182cc73275f1f251075cristy (M20[channel]-M02[channel])+4.0*M11[channel]*M11[channel]; 171057f71289ef12fb275c908972156e7e397d9e07bbcristy channel_moments[channel].invariant[2]=(M30[channel]-3.0*M12[channel])* 17112a22aaab1509397c26047182cc73275f1f251075cristy (M30[channel]-3.0*M12[channel])+(3.0*M21[channel]-M03[channel])* 17122a22aaab1509397c26047182cc73275f1f251075cristy (3.0*M21[channel]-M03[channel]); 171357f71289ef12fb275c908972156e7e397d9e07bbcristy channel_moments[channel].invariant[3]=(M30[channel]+M12[channel])* 17142a22aaab1509397c26047182cc73275f1f251075cristy (M30[channel]+M12[channel])+(M21[channel]+M03[channel])* 17152a22aaab1509397c26047182cc73275f1f251075cristy (M21[channel]+M03[channel]); 171657f71289ef12fb275c908972156e7e397d9e07bbcristy channel_moments[channel].invariant[4]=(M30[channel]-3.0*M12[channel])* 17172a22aaab1509397c26047182cc73275f1f251075cristy (M30[channel]+M12[channel])*((M30[channel]+M12[channel])* 17182a22aaab1509397c26047182cc73275f1f251075cristy (M30[channel]+M12[channel])-3.0*(M21[channel]+M03[channel])* 17192a22aaab1509397c26047182cc73275f1f251075cristy (M21[channel]+M03[channel]))+(3.0*M21[channel]-M03[channel])* 17202a22aaab1509397c26047182cc73275f1f251075cristy (M21[channel]+M03[channel])*(3.0*(M30[channel]+M12[channel])* 17212a22aaab1509397c26047182cc73275f1f251075cristy (M30[channel]+M12[channel])-(M21[channel]+M03[channel])* 17222a22aaab1509397c26047182cc73275f1f251075cristy (M21[channel]+M03[channel])); 172357f71289ef12fb275c908972156e7e397d9e07bbcristy channel_moments[channel].invariant[5]=(M20[channel]-M02[channel])* 17242a22aaab1509397c26047182cc73275f1f251075cristy ((M30[channel]+M12[channel])*(M30[channel]+M12[channel])- 17252a22aaab1509397c26047182cc73275f1f251075cristy (M21[channel]+M03[channel])*(M21[channel]+M03[channel]))+ 17262a22aaab1509397c26047182cc73275f1f251075cristy 4.0*M11[channel]*(M30[channel]+M12[channel])*(M21[channel]+M03[channel]); 172757f71289ef12fb275c908972156e7e397d9e07bbcristy channel_moments[channel].invariant[6]=(3.0*M21[channel]-M03[channel])* 17282a22aaab1509397c26047182cc73275f1f251075cristy (M30[channel]+M12[channel])*((M30[channel]+M12[channel])* 17292a22aaab1509397c26047182cc73275f1f251075cristy (M30[channel]+M12[channel])-3.0*(M21[channel]+M03[channel])* 17302a22aaab1509397c26047182cc73275f1f251075cristy (M21[channel]+M03[channel]))-(M30[channel]-3*M12[channel])* 17312a22aaab1509397c26047182cc73275f1f251075cristy (M21[channel]+M03[channel])*(3.0*(M30[channel]+M12[channel])* 17322a22aaab1509397c26047182cc73275f1f251075cristy (M30[channel]+M12[channel])-(M21[channel]+M03[channel])* 17332a22aaab1509397c26047182cc73275f1f251075cristy (M21[channel]+M03[channel])); 173457f71289ef12fb275c908972156e7e397d9e07bbcristy channel_moments[channel].invariant[7]=M11[channel]*((M30[channel]+ 173557f71289ef12fb275c908972156e7e397d9e07bbcristy M12[channel])*(M30[channel]+M12[channel])-(M03[channel]+M21[channel])* 17362a22aaab1509397c26047182cc73275f1f251075cristy (M03[channel]+M21[channel]))-(M20[channel]-M02[channel])* 17372a22aaab1509397c26047182cc73275f1f251075cristy (M30[channel]+M12[channel])*(M03[channel]+M21[channel]); 17382a22aaab1509397c26047182cc73275f1f251075cristy } 17392a22aaab1509397c26047182cc73275f1f251075cristy if (y < (ssize_t) image->rows) 1740bd4a3c228c0e785517b8ab630b2cc6095373f710cristy channel_moments=(ChannelMoments *) RelinquishMagickMemory(channel_moments); 1741bd4a3c228c0e785517b8ab630b2cc6095373f710cristy return(channel_moments); 17423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 174346f08209f719f4adeea742c45873c2714e80cdb9cristy 17443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* 17453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 17463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 17473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 17483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 1749f8f39d49973e8d7305a84f53f5ad2f569d7cb020cristy% G e t I m a g e C h a n n e l P e r c e p t u a l H a s h % 1750f8f39d49973e8d7305a84f53f5ad2f569d7cb020cristy% % 1751f8f39d49973e8d7305a84f53f5ad2f569d7cb020cristy% % 1752f8f39d49973e8d7305a84f53f5ad2f569d7cb020cristy% % 1753f8f39d49973e8d7305a84f53f5ad2f569d7cb020cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1754f8f39d49973e8d7305a84f53f5ad2f569d7cb020cristy% 1755b3538ec3d53d5853f18e99b510cd855ac870c281cristy% GetImagePerceptualHash() returns the perceptual hash of one or more 1756f8f39d49973e8d7305a84f53f5ad2f569d7cb020cristy% image channels. 1757f8f39d49973e8d7305a84f53f5ad2f569d7cb020cristy% 1758b3538ec3d53d5853f18e99b510cd855ac870c281cristy% The format of the GetImagePerceptualHash method is: 1759f8f39d49973e8d7305a84f53f5ad2f569d7cb020cristy% 1760b3538ec3d53d5853f18e99b510cd855ac870c281cristy% ChannelPerceptualHash *GetImagePerceptualHash(const Image *image, 1761f8f39d49973e8d7305a84f53f5ad2f569d7cb020cristy% ExceptionInfo *exception) 1762f8f39d49973e8d7305a84f53f5ad2f569d7cb020cristy% 1763f8f39d49973e8d7305a84f53f5ad2f569d7cb020cristy% A description of each parameter follows: 1764f8f39d49973e8d7305a84f53f5ad2f569d7cb020cristy% 1765f8f39d49973e8d7305a84f53f5ad2f569d7cb020cristy% o image: the image. 1766f8f39d49973e8d7305a84f53f5ad2f569d7cb020cristy% 1767f8f39d49973e8d7305a84f53f5ad2f569d7cb020cristy% o exception: return any errors or warnings in this structure. 1768f8f39d49973e8d7305a84f53f5ad2f569d7cb020cristy% 1769f8f39d49973e8d7305a84f53f5ad2f569d7cb020cristy*/ 1770f8f39d49973e8d7305a84f53f5ad2f569d7cb020cristy 1771f8f39d49973e8d7305a84f53f5ad2f569d7cb020cristystatic inline double MagickLog10(const double x) 1772f8f39d49973e8d7305a84f53f5ad2f569d7cb020cristy{ 1773f8f39d49973e8d7305a84f53f5ad2f569d7cb020cristy#define Log10Epsilon (1.0e-11) 1774f8f39d49973e8d7305a84f53f5ad2f569d7cb020cristy 1775f8f39d49973e8d7305a84f53f5ad2f569d7cb020cristy if (fabs(x) < Log10Epsilon) 1776f8f39d49973e8d7305a84f53f5ad2f569d7cb020cristy return(log10(Log10Epsilon)); 1777f8f39d49973e8d7305a84f53f5ad2f569d7cb020cristy return(log10(fabs(x))); 1778f8f39d49973e8d7305a84f53f5ad2f569d7cb020cristy} 1779f8f39d49973e8d7305a84f53f5ad2f569d7cb020cristy 1780b3538ec3d53d5853f18e99b510cd855ac870c281cristyMagickExport ChannelPerceptualHash *GetImagePerceptualHash( 1781f8f39d49973e8d7305a84f53f5ad2f569d7cb020cristy const Image *image,ExceptionInfo *exception) 1782f8f39d49973e8d7305a84f53f5ad2f569d7cb020cristy{ 1783f8f39d49973e8d7305a84f53f5ad2f569d7cb020cristy ChannelMoments 1784f8f39d49973e8d7305a84f53f5ad2f569d7cb020cristy *moments; 1785f8f39d49973e8d7305a84f53f5ad2f569d7cb020cristy 1786f8f39d49973e8d7305a84f53f5ad2f569d7cb020cristy ChannelPerceptualHash 1787f8f39d49973e8d7305a84f53f5ad2f569d7cb020cristy *perceptual_hash; 1788f8f39d49973e8d7305a84f53f5ad2f569d7cb020cristy 1789f8f39d49973e8d7305a84f53f5ad2f569d7cb020cristy Image 1790f8f39d49973e8d7305a84f53f5ad2f569d7cb020cristy *hash_image; 1791f8f39d49973e8d7305a84f53f5ad2f569d7cb020cristy 1792f8f39d49973e8d7305a84f53f5ad2f569d7cb020cristy MagickBooleanType 1793f8f39d49973e8d7305a84f53f5ad2f569d7cb020cristy status; 1794f8f39d49973e8d7305a84f53f5ad2f569d7cb020cristy 1795f8f39d49973e8d7305a84f53f5ad2f569d7cb020cristy register ssize_t 1796f8f39d49973e8d7305a84f53f5ad2f569d7cb020cristy i; 1797f8f39d49973e8d7305a84f53f5ad2f569d7cb020cristy 1798f8f39d49973e8d7305a84f53f5ad2f569d7cb020cristy ssize_t 1799f8f39d49973e8d7305a84f53f5ad2f569d7cb020cristy channel; 1800f8f39d49973e8d7305a84f53f5ad2f569d7cb020cristy 1801f8f39d49973e8d7305a84f53f5ad2f569d7cb020cristy /* 1802f8f39d49973e8d7305a84f53f5ad2f569d7cb020cristy Blur then transform to sRGB colorspace. 1803f8f39d49973e8d7305a84f53f5ad2f569d7cb020cristy */ 1804f8f39d49973e8d7305a84f53f5ad2f569d7cb020cristy hash_image=BlurImage(image,0.0,1.0,exception); 1805f8f39d49973e8d7305a84f53f5ad2f569d7cb020cristy if (hash_image == (Image *) NULL) 1806f8f39d49973e8d7305a84f53f5ad2f569d7cb020cristy return((ChannelPerceptualHash *) NULL); 1807f8f39d49973e8d7305a84f53f5ad2f569d7cb020cristy hash_image->depth=8; 1808f8f39d49973e8d7305a84f53f5ad2f569d7cb020cristy status=TransformImageColorspace(hash_image,sRGBColorspace,exception); 1809f8f39d49973e8d7305a84f53f5ad2f569d7cb020cristy if (status == MagickFalse) 1810f8f39d49973e8d7305a84f53f5ad2f569d7cb020cristy return((ChannelPerceptualHash *) NULL); 1811f8f39d49973e8d7305a84f53f5ad2f569d7cb020cristy moments=GetImageMoments(hash_image,exception); 1812f8f39d49973e8d7305a84f53f5ad2f569d7cb020cristy hash_image=DestroyImage(hash_image); 1813f8f39d49973e8d7305a84f53f5ad2f569d7cb020cristy if (moments == (ChannelMoments *) NULL) 1814f8f39d49973e8d7305a84f53f5ad2f569d7cb020cristy return((ChannelPerceptualHash *) NULL); 1815f8f39d49973e8d7305a84f53f5ad2f569d7cb020cristy perceptual_hash=(ChannelPerceptualHash *) AcquireQuantumMemory( 181650debe5028731f7b7218c99c9c70e87ae5d43832Cristy MaxPixelChannels+1UL,sizeof(*perceptual_hash)); 1817f8f39d49973e8d7305a84f53f5ad2f569d7cb020cristy if (perceptual_hash == (ChannelPerceptualHash *) NULL) 1818f8f39d49973e8d7305a84f53f5ad2f569d7cb020cristy return((ChannelPerceptualHash *) NULL); 1819f8f39d49973e8d7305a84f53f5ad2f569d7cb020cristy for (channel=0; channel <= MaxPixelChannels; channel++) 18203ac6aa903557af75f8149bad7c8aa512158fa445cristy for (i=0; i < MaximumNumberOfImageMoments; i++) 1821c018762fb6f380c9d0b1057ec2390e7422ab5178cristy perceptual_hash[channel].srgb_hu_phash[i]= 182257f71289ef12fb275c908972156e7e397d9e07bbcristy (-MagickLog10(moments[channel].invariant[i])); 1823f8f39d49973e8d7305a84f53f5ad2f569d7cb020cristy moments=(ChannelMoments *) RelinquishMagickMemory(moments); 1824f8f39d49973e8d7305a84f53f5ad2f569d7cb020cristy /* 1825f8f39d49973e8d7305a84f53f5ad2f569d7cb020cristy Blur then transform to HCLp colorspace. 1826f8f39d49973e8d7305a84f53f5ad2f569d7cb020cristy */ 1827f8f39d49973e8d7305a84f53f5ad2f569d7cb020cristy hash_image=BlurImage(image,0.0,1.0,exception); 1828f8f39d49973e8d7305a84f53f5ad2f569d7cb020cristy if (hash_image == (Image *) NULL) 1829f8f39d49973e8d7305a84f53f5ad2f569d7cb020cristy { 1830f8f39d49973e8d7305a84f53f5ad2f569d7cb020cristy perceptual_hash=(ChannelPerceptualHash *) RelinquishMagickMemory( 1831f8f39d49973e8d7305a84f53f5ad2f569d7cb020cristy perceptual_hash); 1832f8f39d49973e8d7305a84f53f5ad2f569d7cb020cristy return((ChannelPerceptualHash *) NULL); 1833f8f39d49973e8d7305a84f53f5ad2f569d7cb020cristy } 1834f8f39d49973e8d7305a84f53f5ad2f569d7cb020cristy hash_image->depth=8; 1835f8f39d49973e8d7305a84f53f5ad2f569d7cb020cristy status=TransformImageColorspace(hash_image,HCLpColorspace,exception); 1836f8f39d49973e8d7305a84f53f5ad2f569d7cb020cristy if (status == MagickFalse) 1837f8f39d49973e8d7305a84f53f5ad2f569d7cb020cristy { 1838f8f39d49973e8d7305a84f53f5ad2f569d7cb020cristy perceptual_hash=(ChannelPerceptualHash *) RelinquishMagickMemory( 1839f8f39d49973e8d7305a84f53f5ad2f569d7cb020cristy perceptual_hash); 1840f8f39d49973e8d7305a84f53f5ad2f569d7cb020cristy return((ChannelPerceptualHash *) NULL); 1841f8f39d49973e8d7305a84f53f5ad2f569d7cb020cristy } 1842f8f39d49973e8d7305a84f53f5ad2f569d7cb020cristy moments=GetImageMoments(hash_image,exception); 1843f8f39d49973e8d7305a84f53f5ad2f569d7cb020cristy hash_image=DestroyImage(hash_image); 1844f8f39d49973e8d7305a84f53f5ad2f569d7cb020cristy if (moments == (ChannelMoments *) NULL) 1845f8f39d49973e8d7305a84f53f5ad2f569d7cb020cristy { 1846f8f39d49973e8d7305a84f53f5ad2f569d7cb020cristy perceptual_hash=(ChannelPerceptualHash *) RelinquishMagickMemory( 1847f8f39d49973e8d7305a84f53f5ad2f569d7cb020cristy perceptual_hash); 1848f8f39d49973e8d7305a84f53f5ad2f569d7cb020cristy return((ChannelPerceptualHash *) NULL); 1849f8f39d49973e8d7305a84f53f5ad2f569d7cb020cristy } 1850f8f39d49973e8d7305a84f53f5ad2f569d7cb020cristy for (channel=0; channel <= MaxPixelChannels; channel++) 18513ac6aa903557af75f8149bad7c8aa512158fa445cristy for (i=0; i < MaximumNumberOfImageMoments; i++) 1852c018762fb6f380c9d0b1057ec2390e7422ab5178cristy perceptual_hash[channel].hclp_hu_phash[i]= 185357f71289ef12fb275c908972156e7e397d9e07bbcristy (-MagickLog10(moments[channel].invariant[i])); 1854f8f39d49973e8d7305a84f53f5ad2f569d7cb020cristy moments=(ChannelMoments *) RelinquishMagickMemory(moments); 1855f8f39d49973e8d7305a84f53f5ad2f569d7cb020cristy return(perceptual_hash); 1856f8f39d49973e8d7305a84f53f5ad2f569d7cb020cristy} 1857f8f39d49973e8d7305a84f53f5ad2f569d7cb020cristy 1858f8f39d49973e8d7305a84f53f5ad2f569d7cb020cristy/* 1859f8f39d49973e8d7305a84f53f5ad2f569d7cb020cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1860f8f39d49973e8d7305a84f53f5ad2f569d7cb020cristy% % 1861f8f39d49973e8d7305a84f53f5ad2f569d7cb020cristy% % 1862f8f39d49973e8d7305a84f53f5ad2f569d7cb020cristy% % 1863d42d995b9cb2a16e13221e665554417a5b7ec7fbcristy% G e t I m a g e R a n g e % 18643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 18653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 18663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 18673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 18683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 1869d42d995b9cb2a16e13221e665554417a5b7ec7fbcristy% GetImageRange() returns the range of one or more image channels. 18703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 1871d42d995b9cb2a16e13221e665554417a5b7ec7fbcristy% The format of the GetImageRange method is: 18723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 1873d42d995b9cb2a16e13221e665554417a5b7ec7fbcristy% MagickBooleanType GetImageRange(const Image *image,double *minima, 1874d42d995b9cb2a16e13221e665554417a5b7ec7fbcristy% double *maxima,ExceptionInfo *exception) 18753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 18763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% A description of each parameter follows: 18773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 18783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o image: the image. 18793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 18803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o minima: the minimum value in the channel. 18813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 18823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o maxima: the maximum value in the channel. 18833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 18843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o exception: return any errors or warnings in this structure. 18853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 18863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/ 1887d42d995b9cb2a16e13221e665554417a5b7ec7fbcristyMagickExport MagickBooleanType GetImageRange(const Image *image,double *minima, 1888d42d995b9cb2a16e13221e665554417a5b7ec7fbcristy double *maxima,ExceptionInfo *exception) 18893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 18904a9be6876d64847303b0a02f831a48d6a7fa3c5ccristy CacheView 18914a9be6876d64847303b0a02f831a48d6a7fa3c5ccristy *image_view; 18924a9be6876d64847303b0a02f831a48d6a7fa3c5ccristy 18934a9be6876d64847303b0a02f831a48d6a7fa3c5ccristy MagickBooleanType 18942729a440ea51d1e8ad8a4b9dcc4946bc7168ff1ecristy initialize, 18954a9be6876d64847303b0a02f831a48d6a7fa3c5ccristy status; 18963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 18979d314ff2c17a77996c05413c2013880387e50f0ecristy ssize_t 18989d314ff2c17a77996c05413c2013880387e50f0ecristy y; 18999d314ff2c17a77996c05413c2013880387e50f0ecristy 19003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy assert(image != (Image *) NULL); 1901e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy assert(image->signature == MagickCoreSignature); 19023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (image->debug != MagickFalse) 19033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); 19044a9be6876d64847303b0a02f831a48d6a7fa3c5ccristy status=MagickTrue; 19052729a440ea51d1e8ad8a4b9dcc4946bc7168ff1ecristy initialize=MagickTrue; 19062729a440ea51d1e8ad8a4b9dcc4946bc7168ff1ecristy *maxima=0.0; 19072729a440ea51d1e8ad8a4b9dcc4946bc7168ff1ecristy *minima=0.0; 190846ff2676b1044ea4101ac7a59b83289cd8f6cfdacristy image_view=AcquireVirtualCacheView(image,exception); 19094a9be6876d64847303b0a02f831a48d6a7fa3c5ccristy#if defined(MAGICKCORE_OPENMP_SUPPORT) 19109a5a52fdbea9190e1c868ba9298a6f64d1c896d1cristy #pragma omp parallel for schedule(static,4) shared(status,initialize) \ 19115e6b259130f9dbe0da4666f734937017babe573acristy magick_threads(image,image,image->rows,1) 19124a9be6876d64847303b0a02f831a48d6a7fa3c5ccristy#endif 1913bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy for (y=0; y < (ssize_t) image->rows; y++) 19143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 191504f8f595a51a10b105729d196ac3ca06a5b9102cdirk double 1916c44a78234bb6cae67df1c068e45bc4ce4565c0f2Cristy row_maxima = 0.0, 1917c44a78234bb6cae67df1c068e45bc4ce4565c0f2Cristy row_minima = 0.0; 191804f8f595a51a10b105729d196ac3ca06a5b9102cdirk 191904f8f595a51a10b105729d196ac3ca06a5b9102cdirk MagickBooleanType 192004f8f595a51a10b105729d196ac3ca06a5b9102cdirk row_initialize; 192104f8f595a51a10b105729d196ac3ca06a5b9102cdirk 19224c08aed51c5899665ade97263692328eea4af106cristy register const Quantum 192305d2ff7ebf21f659f5b11e45afb294e152f4330cdirk *magick_restrict p; 19243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 1925bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy register ssize_t 19263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy x; 19273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 19284a9be6876d64847303b0a02f831a48d6a7fa3c5ccristy if (status == MagickFalse) 19294a9be6876d64847303b0a02f831a48d6a7fa3c5ccristy continue; 19304a9be6876d64847303b0a02f831a48d6a7fa3c5ccristy p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception); 19314c08aed51c5899665ade97263692328eea4af106cristy if (p == (const Quantum *) NULL) 19324a9be6876d64847303b0a02f831a48d6a7fa3c5ccristy { 19334a9be6876d64847303b0a02f831a48d6a7fa3c5ccristy status=MagickFalse; 19344a9be6876d64847303b0a02f831a48d6a7fa3c5ccristy continue; 19354a9be6876d64847303b0a02f831a48d6a7fa3c5ccristy } 193604f8f595a51a10b105729d196ac3ca06a5b9102cdirk row_initialize=MagickTrue; 1937bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy for (x=0; x < (ssize_t) image->columns; x++) 19383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 19394a9be6876d64847303b0a02f831a48d6a7fa3c5ccristy register ssize_t 19404a9be6876d64847303b0a02f831a48d6a7fa3c5ccristy i; 19414a9be6876d64847303b0a02f831a48d6a7fa3c5ccristy 1942883fde11debec15cedb05dc5d7228d8588066bc0cristy if (GetPixelReadMask(image,p) == 0) 194310a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy { 194410a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy p+=GetPixelChannels(image); 194510a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy continue; 194610a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy } 19474a9be6876d64847303b0a02f831a48d6a7fa3c5ccristy for (i=0; i < (ssize_t) GetPixelChannels(image); i++) 19484a9be6876d64847303b0a02f831a48d6a7fa3c5ccristy { 19495a23c55ddcfdf6ae717dd42d8a1c1a2ff8c6305fcristy PixelChannel channel=GetPixelChannelChannel(image,i); 19505a23c55ddcfdf6ae717dd42d8a1c1a2ff8c6305fcristy PixelTrait traits=GetPixelChannelTraits(image,channel); 19514a9be6876d64847303b0a02f831a48d6a7fa3c5ccristy if (traits == UndefinedPixelTrait) 19524a9be6876d64847303b0a02f831a48d6a7fa3c5ccristy continue; 19534a9be6876d64847303b0a02f831a48d6a7fa3c5ccristy if ((traits & UpdatePixelTrait) == 0) 19544a9be6876d64847303b0a02f831a48d6a7fa3c5ccristy continue; 195504f8f595a51a10b105729d196ac3ca06a5b9102cdirk if (row_initialize != MagickFalse) 195604f8f595a51a10b105729d196ac3ca06a5b9102cdirk { 195704f8f595a51a10b105729d196ac3ca06a5b9102cdirk row_minima=(double) p[i]; 195804f8f595a51a10b105729d196ac3ca06a5b9102cdirk row_maxima=(double) p[i]; 195904f8f595a51a10b105729d196ac3ca06a5b9102cdirk row_initialize=MagickFalse; 196004f8f595a51a10b105729d196ac3ca06a5b9102cdirk } 196104f8f595a51a10b105729d196ac3ca06a5b9102cdirk else 196204f8f595a51a10b105729d196ac3ca06a5b9102cdirk { 196304f8f595a51a10b105729d196ac3ca06a5b9102cdirk if ((double) p[i] < row_minima) 196404f8f595a51a10b105729d196ac3ca06a5b9102cdirk row_minima=(double) p[i]; 196504f8f595a51a10b105729d196ac3ca06a5b9102cdirk if ((double) p[i] > row_maxima) 196604f8f595a51a10b105729d196ac3ca06a5b9102cdirk row_maxima=(double) p[i]; 196704f8f595a51a10b105729d196ac3ca06a5b9102cdirk } 196804f8f595a51a10b105729d196ac3ca06a5b9102cdirk } 196904f8f595a51a10b105729d196ac3ca06a5b9102cdirk p+=GetPixelChannels(image); 197004f8f595a51a10b105729d196ac3ca06a5b9102cdirk } 19714a9be6876d64847303b0a02f831a48d6a7fa3c5ccristy#if defined(MAGICKCORE_OPENMP_SUPPORT) 197204f8f595a51a10b105729d196ac3ca06a5b9102cdirk#pragma omp critical (MagickCore_GetImageRange) 19734a9be6876d64847303b0a02f831a48d6a7fa3c5ccristy#endif 197404f8f595a51a10b105729d196ac3ca06a5b9102cdirk { 197504f8f595a51a10b105729d196ac3ca06a5b9102cdirk if (initialize != MagickFalse) 19763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 197704f8f595a51a10b105729d196ac3ca06a5b9102cdirk *minima=row_minima; 197804f8f595a51a10b105729d196ac3ca06a5b9102cdirk *maxima=row_maxima; 197904f8f595a51a10b105729d196ac3ca06a5b9102cdirk initialize=MagickFalse; 198004f8f595a51a10b105729d196ac3ca06a5b9102cdirk } 198104f8f595a51a10b105729d196ac3ca06a5b9102cdirk else 198204f8f595a51a10b105729d196ac3ca06a5b9102cdirk { 198304f8f595a51a10b105729d196ac3ca06a5b9102cdirk if (row_minima < *minima) 198404f8f595a51a10b105729d196ac3ca06a5b9102cdirk *minima=row_minima; 198504f8f595a51a10b105729d196ac3ca06a5b9102cdirk if (row_maxima > *maxima) 198604f8f595a51a10b105729d196ac3ca06a5b9102cdirk *maxima=row_maxima; 19873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 19883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 19893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 19904a9be6876d64847303b0a02f831a48d6a7fa3c5ccristy image_view=DestroyCacheView(image_view); 19914a9be6876d64847303b0a02f831a48d6a7fa3c5ccristy return(status); 19923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 19933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 19943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* 19953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 19963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 19973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 19983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 1999d42d995b9cb2a16e13221e665554417a5b7ec7fbcristy% G e t I m a g e S t a t i s t i c s % 20003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 20013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 20023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 20033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 20043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 20055048d30ffd6670a4b4c9986bbcb46b228afdd884cristy% GetImageStatistics() returns statistics for each channel in the image. The 20065048d30ffd6670a4b4c9986bbcb46b228afdd884cristy% statistics include the channel depth, its minima, maxima, mean, standard 20075048d30ffd6670a4b4c9986bbcb46b228afdd884cristy% deviation, kurtosis and skewness. You can access the red channel mean, for 20085048d30ffd6670a4b4c9986bbcb46b228afdd884cristy% example, like this: 20093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 2010d42d995b9cb2a16e13221e665554417a5b7ec7fbcristy% channel_statistics=GetImageStatistics(image,exception); 201149dd6a0c1bab5e1e6f99369c0f70a5e0184810d4cristy% red_mean=channel_statistics[RedPixelChannel].mean; 20123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 20133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% Use MagickRelinquishMemory() to free the statistics buffer. 20143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 2015d42d995b9cb2a16e13221e665554417a5b7ec7fbcristy% The format of the GetImageStatistics method is: 20163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 2017d42d995b9cb2a16e13221e665554417a5b7ec7fbcristy% ChannelStatistics *GetImageStatistics(const Image *image, 20183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% ExceptionInfo *exception) 20193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 20203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% A description of each parameter follows: 20213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 20223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o image: the image. 20233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 20243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o exception: return any errors or warnings in this structure. 20253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 20263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/ 2027d42d995b9cb2a16e13221e665554417a5b7ec7fbcristyMagickExport ChannelStatistics *GetImageStatistics(const Image *image, 20283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy ExceptionInfo *exception) 20293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 20303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy ChannelStatistics 20313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *channel_statistics; 20323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 203381c3360b2dfd109013aa2116eeb3a3caa29dd362cristy double 203481c3360b2dfd109013aa2116eeb3a3caa29dd362cristy *histogram; 203581c3360b2dfd109013aa2116eeb3a3caa29dd362cristy 20363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy MagickStatusType 20373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy status; 20383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 20393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy QuantumAny 20403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy range; 20413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 2042bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy register ssize_t 20433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy i; 20443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 20453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy size_t 20469d314ff2c17a77996c05413c2013880387e50f0ecristy channels, 204749dd6a0c1bab5e1e6f99369c0f70a5e0184810d4cristy depth; 20483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 20499d314ff2c17a77996c05413c2013880387e50f0ecristy ssize_t 20509d314ff2c17a77996c05413c2013880387e50f0ecristy y; 20513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 20523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy assert(image != (Image *) NULL); 2053e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy assert(image->signature == MagickCoreSignature); 20543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (image->debug != MagickFalse) 20553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); 2056d0f9c810bc403c9ffa931c001e57664670be931fcristy histogram=(double *) AcquireQuantumMemory(MaxMap+1UL,MaxPixelChannels* 205781c3360b2dfd109013aa2116eeb3a3caa29dd362cristy sizeof(*histogram)); 205849dd6a0c1bab5e1e6f99369c0f70a5e0184810d4cristy channel_statistics=(ChannelStatistics *) AcquireQuantumMemory( 205949dd6a0c1bab5e1e6f99369c0f70a5e0184810d4cristy MaxPixelChannels+1,sizeof(*channel_statistics)); 206081c3360b2dfd109013aa2116eeb3a3caa29dd362cristy if ((channel_statistics == (ChannelStatistics *) NULL) || 206181c3360b2dfd109013aa2116eeb3a3caa29dd362cristy (histogram == (double *) NULL)) 206281c3360b2dfd109013aa2116eeb3a3caa29dd362cristy { 206381c3360b2dfd109013aa2116eeb3a3caa29dd362cristy if (histogram != (double *) NULL) 206481c3360b2dfd109013aa2116eeb3a3caa29dd362cristy histogram=(double *) RelinquishMagickMemory(histogram); 206581c3360b2dfd109013aa2116eeb3a3caa29dd362cristy if (channel_statistics != (ChannelStatistics *) NULL) 206681c3360b2dfd109013aa2116eeb3a3caa29dd362cristy channel_statistics=(ChannelStatistics *) RelinquishMagickMemory( 206781c3360b2dfd109013aa2116eeb3a3caa29dd362cristy channel_statistics); 206881c3360b2dfd109013aa2116eeb3a3caa29dd362cristy return(channel_statistics); 206981c3360b2dfd109013aa2116eeb3a3caa29dd362cristy } 207049dd6a0c1bab5e1e6f99369c0f70a5e0184810d4cristy (void) ResetMagickMemory(channel_statistics,0,(MaxPixelChannels+1)* 20713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy sizeof(*channel_statistics)); 207225a5f2fa49cd7276c378ee37cb0afb5e2182a433cristy for (i=0; i <= (ssize_t) MaxPixelChannels; i++) 20733e37d9e8095bc3876bd4ff214d8ac33513ddb12bcristy { 20743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy channel_statistics[i].depth=1; 2075fe181a767c3b3e61b9133829c504e75e34916de8cristy channel_statistics[i].maxima=(-MagickMaximumValue); 2076fe181a767c3b3e61b9133829c504e75e34916de8cristy channel_statistics[i].minima=MagickMaximumValue; 20773e37d9e8095bc3876bd4ff214d8ac33513ddb12bcristy } 2078d0f9c810bc403c9ffa931c001e57664670be931fcristy (void) ResetMagickMemory(histogram,0,(MaxMap+1)*MaxPixelChannels* 207981c3360b2dfd109013aa2116eeb3a3caa29dd362cristy sizeof(*histogram)); 2080bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy for (y=0; y < (ssize_t) image->rows; y++) 20813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 20824c08aed51c5899665ade97263692328eea4af106cristy register const Quantum 208305d2ff7ebf21f659f5b11e45afb294e152f4330cdirk *magick_restrict p; 20843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 2085bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy register ssize_t 20863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy x; 20873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 20883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy p=GetVirtualPixels(image,0,y,image->columns,1,exception); 20894c08aed51c5899665ade97263692328eea4af106cristy if (p == (const Quantum *) NULL) 20903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 209149dd6a0c1bab5e1e6f99369c0f70a5e0184810d4cristy for (x=0; x < (ssize_t) image->columns; x++) 20923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 209349dd6a0c1bab5e1e6f99369c0f70a5e0184810d4cristy register ssize_t 209449dd6a0c1bab5e1e6f99369c0f70a5e0184810d4cristy i; 209549dd6a0c1bab5e1e6f99369c0f70a5e0184810d4cristy 2096883fde11debec15cedb05dc5d7228d8588066bc0cristy if (GetPixelReadMask(image,p) == 0) 209710a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy { 209810a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy p+=GetPixelChannels(image); 209910a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy continue; 210010a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy } 210149dd6a0c1bab5e1e6f99369c0f70a5e0184810d4cristy for (i=0; i < (ssize_t) GetPixelChannels(image); i++) 210249dd6a0c1bab5e1e6f99369c0f70a5e0184810d4cristy { 21035a23c55ddcfdf6ae717dd42d8a1c1a2ff8c6305fcristy PixelChannel channel=GetPixelChannelChannel(image,i); 21045a23c55ddcfdf6ae717dd42d8a1c1a2ff8c6305fcristy PixelTrait traits=GetPixelChannelTraits(image,channel); 210549dd6a0c1bab5e1e6f99369c0f70a5e0184810d4cristy if (traits == UndefinedPixelTrait) 210649dd6a0c1bab5e1e6f99369c0f70a5e0184810d4cristy continue; 21073cad9cd91c3f7cb8b1d7379c0931623220bab523cristy if (channel_statistics[channel].depth != MAGICKCORE_QUANTUM_DEPTH) 210849dd6a0c1bab5e1e6f99369c0f70a5e0184810d4cristy { 21093cad9cd91c3f7cb8b1d7379c0931623220bab523cristy depth=channel_statistics[channel].depth; 211049dd6a0c1bab5e1e6f99369c0f70a5e0184810d4cristy range=GetQuantumRange(depth); 211149dd6a0c1bab5e1e6f99369c0f70a5e0184810d4cristy status=p[i] != ScaleAnyToQuantum(ScaleQuantumToAny(p[i],range), 211249dd6a0c1bab5e1e6f99369c0f70a5e0184810d4cristy range) ? MagickTrue : MagickFalse; 211349dd6a0c1bab5e1e6f99369c0f70a5e0184810d4cristy if (status != MagickFalse) 211449dd6a0c1bab5e1e6f99369c0f70a5e0184810d4cristy { 2115cd8ce3e1bebfd93cbfee86e2e489907000945053cristy channel_statistics[channel].depth++; 21166f7d3a9b4da141841c306f024b4944f5d8b8431fcristy i--; 211749dd6a0c1bab5e1e6f99369c0f70a5e0184810d4cristy continue; 211849dd6a0c1bab5e1e6f99369c0f70a5e0184810d4cristy } 21193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 21203e37d9e8095bc3876bd4ff214d8ac33513ddb12bcristy if ((double) p[i] < channel_statistics[channel].minima) 21213e37d9e8095bc3876bd4ff214d8ac33513ddb12bcristy channel_statistics[channel].minima=(double) p[i]; 21223e37d9e8095bc3876bd4ff214d8ac33513ddb12bcristy if ((double) p[i] > channel_statistics[channel].maxima) 21233e37d9e8095bc3876bd4ff214d8ac33513ddb12bcristy channel_statistics[channel].maxima=(double) p[i]; 2124cd8ce3e1bebfd93cbfee86e2e489907000945053cristy channel_statistics[channel].sum+=p[i]; 2125cd8ce3e1bebfd93cbfee86e2e489907000945053cristy channel_statistics[channel].sum_squared+=(double) p[i]*p[i]; 2126cd8ce3e1bebfd93cbfee86e2e489907000945053cristy channel_statistics[channel].sum_cubed+=(double) p[i]*p[i]*p[i]; 2127cd8ce3e1bebfd93cbfee86e2e489907000945053cristy channel_statistics[channel].sum_fourth_power+=(double) p[i]*p[i]*p[i]* 2128cd8ce3e1bebfd93cbfee86e2e489907000945053cristy p[i]; 21295048d30ffd6670a4b4c9986bbcb46b228afdd884cristy channel_statistics[channel].area++; 213081c3360b2dfd109013aa2116eeb3a3caa29dd362cristy histogram[GetPixelChannels(image)*ScaleQuantumToMap( 213181c3360b2dfd109013aa2116eeb3a3caa29dd362cristy ClampToQuantum((double) p[i]))+i]++; 213249dd6a0c1bab5e1e6f99369c0f70a5e0184810d4cristy } 2133ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy p+=GetPixelChannels(image); 21343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 21353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 213625a5f2fa49cd7276c378ee37cb0afb5e2182a433cristy for (i=0; i < (ssize_t) MaxPixelChannels; i++) 21373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 2138a38fb2c21b8d9b37615b279b45d0547596796ddccristy double 2139a42b4f3db63a5cf1f29a348d55dfd625baf59e30cristy area, 2140a42b4f3db63a5cf1f29a348d55dfd625baf59e30cristy number_bins; 2141a38fb2c21b8d9b37615b279b45d0547596796ddccristy 214281c3360b2dfd109013aa2116eeb3a3caa29dd362cristy register ssize_t 214381c3360b2dfd109013aa2116eeb3a3caa29dd362cristy j; 214481c3360b2dfd109013aa2116eeb3a3caa29dd362cristy 21453e3ec3afbb0782697f201cbe30a56794c10dc7efcristy area=PerceptibleReciprocal(channel_statistics[i].area); 2146a38fb2c21b8d9b37615b279b45d0547596796ddccristy channel_statistics[i].sum*=area; 2147a38fb2c21b8d9b37615b279b45d0547596796ddccristy channel_statistics[i].sum_squared*=area; 2148a38fb2c21b8d9b37615b279b45d0547596796ddccristy channel_statistics[i].sum_cubed*=area; 2149a38fb2c21b8d9b37615b279b45d0547596796ddccristy channel_statistics[i].sum_fourth_power*=area; 2150fd9dcd4a312944c590a433c5d519146364fa6932cristy channel_statistics[i].mean=channel_statistics[i].sum; 2151fd9dcd4a312944c590a433c5d519146364fa6932cristy channel_statistics[i].variance=channel_statistics[i].sum_squared; 2152fd9dcd4a312944c590a433c5d519146364fa6932cristy channel_statistics[i].standard_deviation=sqrt( 2153fd9dcd4a312944c590a433c5d519146364fa6932cristy channel_statistics[i].variance-(channel_statistics[i].mean* 2154fd9dcd4a312944c590a433c5d519146364fa6932cristy channel_statistics[i].mean)); 2155a42b4f3db63a5cf1f29a348d55dfd625baf59e30cristy number_bins=0.0; 2156a42b4f3db63a5cf1f29a348d55dfd625baf59e30cristy for (j=0; j < (ssize_t) (MaxMap+1U); j++) 2157a42b4f3db63a5cf1f29a348d55dfd625baf59e30cristy if (histogram[GetPixelChannels(image)*j+i] > 0.0) 2158a42b4f3db63a5cf1f29a348d55dfd625baf59e30cristy number_bins++; 21597a61d4cc5307ed5b767f9b6115de23f542d998a3cristy for (j=0; j < (ssize_t) (MaxMap+1U); j++) 21607a61d4cc5307ed5b767f9b6115de23f542d998a3cristy { 21617a61d4cc5307ed5b767f9b6115de23f542d998a3cristy double 21627a61d4cc5307ed5b767f9b6115de23f542d998a3cristy count; 216381c3360b2dfd109013aa2116eeb3a3caa29dd362cristy 21647a61d4cc5307ed5b767f9b6115de23f542d998a3cristy count=histogram[GetPixelChannels(image)*j+i]*area; 21657a61d4cc5307ed5b767f9b6115de23f542d998a3cristy channel_statistics[i].entropy+=-count*MagickLog10(count)/ 2166a42b4f3db63a5cf1f29a348d55dfd625baf59e30cristy MagickLog10(number_bins); 21677a61d4cc5307ed5b767f9b6115de23f542d998a3cristy } 21683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 216925a5f2fa49cd7276c378ee37cb0afb5e2182a433cristy for (i=0; i < (ssize_t) MaxPixelChannels; i++) 21703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 217140a5c455ade0046871a4e93e41585465ff6c575acristy PixelTrait traits=GetPixelChannelTraits(image,(PixelChannel) i); 2172a5bc74d9d068e19282bdafd0c6c39264af465fcdcristy if ((traits & UpdatePixelTrait) == 0) 2173a5bc74d9d068e19282bdafd0c6c39264af465fcdcristy continue; 2174a933607bd9aba71608aa30d9145e54323975b8f0cristy channel_statistics[CompositePixelChannel].area+=channel_statistics[i].area; 2175a50f0c85d273f79dee2726d0ad8481423f4bc5f8cristy channel_statistics[CompositePixelChannel].minima=MagickMin( 21765f95f4f77efc46ff53593d750491c8f60698c983cristy channel_statistics[CompositePixelChannel].minima, 217732daba40c8ba87808abfe7d4bfec678d073cd63fcristy channel_statistics[i].minima); 2178a50f0c85d273f79dee2726d0ad8481423f4bc5f8cristy channel_statistics[CompositePixelChannel].maxima=EvaluateMax( 21795f95f4f77efc46ff53593d750491c8f60698c983cristy channel_statistics[CompositePixelChannel].maxima, 218032daba40c8ba87808abfe7d4bfec678d073cd63fcristy channel_statistics[i].maxima); 21815f95f4f77efc46ff53593d750491c8f60698c983cristy channel_statistics[CompositePixelChannel].sum+=channel_statistics[i].sum; 21825f95f4f77efc46ff53593d750491c8f60698c983cristy channel_statistics[CompositePixelChannel].sum_squared+= 2183fd9dcd4a312944c590a433c5d519146364fa6932cristy channel_statistics[i].sum_squared; 21845f95f4f77efc46ff53593d750491c8f60698c983cristy channel_statistics[CompositePixelChannel].sum_cubed+= 218532daba40c8ba87808abfe7d4bfec678d073cd63fcristy channel_statistics[i].sum_cubed; 21865f95f4f77efc46ff53593d750491c8f60698c983cristy channel_statistics[CompositePixelChannel].sum_fourth_power+= 2187a8178ed437f3602d0290c41ebeccb51bb9ecccd7cristy channel_statistics[i].sum_fourth_power; 21885f95f4f77efc46ff53593d750491c8f60698c983cristy channel_statistics[CompositePixelChannel].mean+=channel_statistics[i].mean; 21895f95f4f77efc46ff53593d750491c8f60698c983cristy channel_statistics[CompositePixelChannel].variance+= 219032daba40c8ba87808abfe7d4bfec678d073cd63fcristy channel_statistics[i].variance-channel_statistics[i].mean* 219132daba40c8ba87808abfe7d4bfec678d073cd63fcristy channel_statistics[i].mean; 21925f95f4f77efc46ff53593d750491c8f60698c983cristy channel_statistics[CompositePixelChannel].standard_deviation+= 2193fd9dcd4a312944c590a433c5d519146364fa6932cristy channel_statistics[i].variance-channel_statistics[i].mean* 2194fd9dcd4a312944c590a433c5d519146364fa6932cristy channel_statistics[i].mean; 21957a61d4cc5307ed5b767f9b6115de23f542d998a3cristy if (channel_statistics[i].entropy > MagickEpsilon) 21967a61d4cc5307ed5b767f9b6115de23f542d998a3cristy channel_statistics[CompositePixelChannel].entropy+= 21977a61d4cc5307ed5b767f9b6115de23f542d998a3cristy channel_statistics[i].entropy; 21983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 219949dd6a0c1bab5e1e6f99369c0f70a5e0184810d4cristy channels=GetImageChannels(image); 2200a933607bd9aba71608aa30d9145e54323975b8f0cristy channel_statistics[CompositePixelChannel].area/=channels; 22015f95f4f77efc46ff53593d750491c8f60698c983cristy channel_statistics[CompositePixelChannel].sum/=channels; 22025f95f4f77efc46ff53593d750491c8f60698c983cristy channel_statistics[CompositePixelChannel].sum_squared/=channels; 22035f95f4f77efc46ff53593d750491c8f60698c983cristy channel_statistics[CompositePixelChannel].sum_cubed/=channels; 22045f95f4f77efc46ff53593d750491c8f60698c983cristy channel_statistics[CompositePixelChannel].sum_fourth_power/=channels; 22055f95f4f77efc46ff53593d750491c8f60698c983cristy channel_statistics[CompositePixelChannel].mean/=channels; 22065f95f4f77efc46ff53593d750491c8f60698c983cristy channel_statistics[CompositePixelChannel].variance/=channels; 22075f95f4f77efc46ff53593d750491c8f60698c983cristy channel_statistics[CompositePixelChannel].standard_deviation= 22085f95f4f77efc46ff53593d750491c8f60698c983cristy sqrt(channel_statistics[CompositePixelChannel].standard_deviation/channels); 22095f95f4f77efc46ff53593d750491c8f60698c983cristy channel_statistics[CompositePixelChannel].kurtosis/=channels; 22105f95f4f77efc46ff53593d750491c8f60698c983cristy channel_statistics[CompositePixelChannel].skewness/=channels; 221181c3360b2dfd109013aa2116eeb3a3caa29dd362cristy channel_statistics[CompositePixelChannel].entropy/=channels; 221225a5f2fa49cd7276c378ee37cb0afb5e2182a433cristy for (i=0; i <= (ssize_t) MaxPixelChannels; i++) 22133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 2214a38fb2c21b8d9b37615b279b45d0547596796ddccristy double 2215a38fb2c21b8d9b37615b279b45d0547596796ddccristy standard_deviation; 2216a38fb2c21b8d9b37615b279b45d0547596796ddccristy 22176d94a308cc4b42b09f5020acce05d779e24faa47cristy if (channel_statistics[i].standard_deviation == 0.0) 22186d94a308cc4b42b09f5020acce05d779e24faa47cristy continue; 22193e3ec3afbb0782697f201cbe30a56794c10dc7efcristy standard_deviation=PerceptibleReciprocal( 2220a38fb2c21b8d9b37615b279b45d0547596796ddccristy channel_statistics[i].standard_deviation); 2221e2a912b6c9086c98ec838baa0824cd8deca55538cristy channel_statistics[i].skewness=(channel_statistics[i].sum_cubed-3.0* 2222e2a912b6c9086c98ec838baa0824cd8deca55538cristy channel_statistics[i].mean*channel_statistics[i].sum_squared+2.0* 2223e2a912b6c9086c98ec838baa0824cd8deca55538cristy channel_statistics[i].mean*channel_statistics[i].mean* 2224a38fb2c21b8d9b37615b279b45d0547596796ddccristy channel_statistics[i].mean)*(standard_deviation*standard_deviation* 2225a38fb2c21b8d9b37615b279b45d0547596796ddccristy standard_deviation); 2226e2a912b6c9086c98ec838baa0824cd8deca55538cristy channel_statistics[i].kurtosis=(channel_statistics[i].sum_fourth_power-4.0* 2227e2a912b6c9086c98ec838baa0824cd8deca55538cristy channel_statistics[i].mean*channel_statistics[i].sum_cubed+6.0* 2228e2a912b6c9086c98ec838baa0824cd8deca55538cristy channel_statistics[i].mean*channel_statistics[i].mean* 2229a8178ed437f3602d0290c41ebeccb51bb9ecccd7cristy channel_statistics[i].sum_squared-3.0*channel_statistics[i].mean* 2230a8178ed437f3602d0290c41ebeccb51bb9ecccd7cristy channel_statistics[i].mean*1.0*channel_statistics[i].mean* 2231a38fb2c21b8d9b37615b279b45d0547596796ddccristy channel_statistics[i].mean)*(standard_deviation*standard_deviation* 2232a38fb2c21b8d9b37615b279b45d0547596796ddccristy standard_deviation*standard_deviation)-3.0; 22333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 223481c3360b2dfd109013aa2116eeb3a3caa29dd362cristy histogram=(double *) RelinquishMagickMemory(histogram); 2235e287bbaee17bb627af090e3127082e5a316337e5cristy if (y < (ssize_t) image->rows) 2236e287bbaee17bb627af090e3127082e5a316337e5cristy channel_statistics=(ChannelStatistics *) RelinquishMagickMemory( 2237e287bbaee17bb627af090e3127082e5a316337e5cristy channel_statistics); 22383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return(channel_statistics); 22393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 224099bd523143cfe6d0407e260adf99d7384c30532dcristy 224199bd523143cfe6d0407e260adf99d7384c30532dcristy/* 224299bd523143cfe6d0407e260adf99d7384c30532dcristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 224399bd523143cfe6d0407e260adf99d7384c30532dcristy% % 224499bd523143cfe6d0407e260adf99d7384c30532dcristy% % 2245f56e6ad6da167beca48fb23194201c25cd3dfb8ecristy% % 2246f56e6ad6da167beca48fb23194201c25cd3dfb8ecristy% P o l y n o m i a l I m a g e % 2247f56e6ad6da167beca48fb23194201c25cd3dfb8ecristy% % 2248f56e6ad6da167beca48fb23194201c25cd3dfb8ecristy% % 2249f56e6ad6da167beca48fb23194201c25cd3dfb8ecristy% % 2250f56e6ad6da167beca48fb23194201c25cd3dfb8ecristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2251f56e6ad6da167beca48fb23194201c25cd3dfb8ecristy% 2252f56e6ad6da167beca48fb23194201c25cd3dfb8ecristy% PolynomialImage() returns a new image where each pixel is the sum of the 2253f56e6ad6da167beca48fb23194201c25cd3dfb8ecristy% pixels in the image sequence after applying its corresponding terms 2254dbc2da927c5fcf9d3518af20203fa5bc32e572a0cristy% (coefficient and degree pairs). 2255f56e6ad6da167beca48fb23194201c25cd3dfb8ecristy% 2256f56e6ad6da167beca48fb23194201c25cd3dfb8ecristy% The format of the PolynomialImage method is: 2257f56e6ad6da167beca48fb23194201c25cd3dfb8ecristy% 225841f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy% Image *PolynomialImage(const Image *images,const size_t number_terms, 2259f56e6ad6da167beca48fb23194201c25cd3dfb8ecristy% const double *terms,ExceptionInfo *exception) 2260f56e6ad6da167beca48fb23194201c25cd3dfb8ecristy% 2261f56e6ad6da167beca48fb23194201c25cd3dfb8ecristy% A description of each parameter follows: 2262f56e6ad6da167beca48fb23194201c25cd3dfb8ecristy% 226341f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy% o images: the image sequence. 2264f56e6ad6da167beca48fb23194201c25cd3dfb8ecristy% 2265f56e6ad6da167beca48fb23194201c25cd3dfb8ecristy% o number_terms: the number of terms in the list. The actual list length 2266f56e6ad6da167beca48fb23194201c25cd3dfb8ecristy% is 2 x number_terms + 1 (the constant). 2267f56e6ad6da167beca48fb23194201c25cd3dfb8ecristy% 2268f56e6ad6da167beca48fb23194201c25cd3dfb8ecristy% o terms: the list of polynomial coefficients and degree pairs and a 2269f56e6ad6da167beca48fb23194201c25cd3dfb8ecristy% constant. 2270f56e6ad6da167beca48fb23194201c25cd3dfb8ecristy% 2271f56e6ad6da167beca48fb23194201c25cd3dfb8ecristy% o exception: return any errors or warnings in this structure. 2272f56e6ad6da167beca48fb23194201c25cd3dfb8ecristy% 2273f56e6ad6da167beca48fb23194201c25cd3dfb8ecristy*/ 2274f56e6ad6da167beca48fb23194201c25cd3dfb8ecristy 227541f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristyMagickExport Image *PolynomialImage(const Image *images, 2276f56e6ad6da167beca48fb23194201c25cd3dfb8ecristy const size_t number_terms,const double *terms,ExceptionInfo *exception) 2277f56e6ad6da167beca48fb23194201c25cd3dfb8ecristy{ 227841f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy#define PolynomialImageTag "Polynomial/Image" 227941f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy 228041f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy CacheView 228141f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy *polynomial_view; 228241f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy 2283f56e6ad6da167beca48fb23194201c25cd3dfb8ecristy Image 228441f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy *image; 2285f56e6ad6da167beca48fb23194201c25cd3dfb8ecristy 2286f56e6ad6da167beca48fb23194201c25cd3dfb8ecristy MagickBooleanType 2287f56e6ad6da167beca48fb23194201c25cd3dfb8ecristy status; 2288f56e6ad6da167beca48fb23194201c25cd3dfb8ecristy 228941f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy MagickOffsetType 229041f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy progress; 229141f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy 229241f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy PixelChannels 229305d2ff7ebf21f659f5b11e45afb294e152f4330cdirk **magick_restrict polynomial_pixels; 229441f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy 229541f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy size_t 229641f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy number_images; 229741f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy 229841f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy ssize_t 229941f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy y; 230041f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy 230141f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy assert(images != (Image *) NULL); 2302e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy assert(images->signature == MagickCoreSignature); 230341f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy if (images->debug != MagickFalse) 230441f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",images->filename); 2305f56e6ad6da167beca48fb23194201c25cd3dfb8ecristy assert(exception != (ExceptionInfo *) NULL); 2306e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy assert(exception->signature == MagickCoreSignature); 230741f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy image=CloneImage(images,images->columns,images->rows,MagickTrue, 2308f56e6ad6da167beca48fb23194201c25cd3dfb8ecristy exception); 230941f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy if (image == (Image *) NULL) 2310f56e6ad6da167beca48fb23194201c25cd3dfb8ecristy return((Image *) NULL); 231141f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse) 2312f56e6ad6da167beca48fb23194201c25cd3dfb8ecristy { 231341f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy image=DestroyImage(image); 2314f56e6ad6da167beca48fb23194201c25cd3dfb8ecristy return((Image *) NULL); 2315f56e6ad6da167beca48fb23194201c25cd3dfb8ecristy } 231641f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy number_images=GetImageListLength(images); 2317751a6671c9b7480f3672a7ef6aa6e392f064b46ddirk polynomial_pixels=AcquirePixelThreadSet(images); 231841f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy if (polynomial_pixels == (PixelChannels **) NULL) 231941f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy { 232041f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy image=DestroyImage(image); 232141f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy (void) ThrowMagickException(exception,GetMagickModule(), 2322efe601ce9ea5ad34ad0e8ad6e61d9be9b148b2a3cristy ResourceLimitError,"MemoryAllocationFailed","`%s'",images->filename); 232341f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy return((Image *) NULL); 232441f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy } 232541f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy /* 232641f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy Polynomial image pixels. 232741f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy */ 232841f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy status=MagickTrue; 232941f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy progress=0; 233046ff2676b1044ea4101ac7a59b83289cd8f6cfdacristy polynomial_view=AcquireAuthenticCacheView(image,exception); 233141f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy#if defined(MAGICKCORE_OPENMP_SUPPORT) 233241f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy #pragma omp parallel for schedule(static,4) shared(progress,status) \ 23335e6b259130f9dbe0da4666f734937017babe573acristy magick_threads(image,image,image->rows,1) 233441f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy#endif 233541f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy for (y=0; y < (ssize_t) image->rows; y++) 233641f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy { 233741f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy CacheView 233841f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy *image_view; 233941f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy 234041f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy const Image 234141f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy *next; 234241f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy 234341f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy const int 234441f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy id = GetOpenMPThreadId(); 234541f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy 234641f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy register ssize_t 234741f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy i, 234841f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy x; 234941f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy 235041f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy register PixelChannels 235141f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy *polynomial_pixel; 235241f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy 235341f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy register Quantum 235405d2ff7ebf21f659f5b11e45afb294e152f4330cdirk *magick_restrict q; 235541f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy 235641f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy ssize_t 235741f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy j; 235841f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy 235941f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy if (status == MagickFalse) 236041f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy continue; 2361edb3f510ac6109703f134e42f9a2a0cc21866d78cristy q=QueueCacheViewAuthenticPixels(polynomial_view,0,y,image->columns,1, 2362edb3f510ac6109703f134e42f9a2a0cc21866d78cristy exception); 236341f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy if (q == (Quantum *) NULL) 236441f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy { 236541f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy status=MagickFalse; 236641f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy continue; 236741f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy } 236841f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy polynomial_pixel=polynomial_pixels[id]; 236941f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy for (j=0; j < (ssize_t) image->columns; j++) 237041f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy for (i=0; i < MaxPixelChannels; i++) 237141f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy polynomial_pixel[j].channel[i]=0.0; 237241f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy next=images; 237341f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy for (j=0; j < (ssize_t) number_images; j++) 237441f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy { 237541f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy register const Quantum 237641f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy *p; 237741f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy 237802016cff038d0ddb255d4c84bf31a78f5c8714f0cristy if (j >= (ssize_t) number_terms) 237902016cff038d0ddb255d4c84bf31a78f5c8714f0cristy continue; 238046ff2676b1044ea4101ac7a59b83289cd8f6cfdacristy image_view=AcquireVirtualCacheView(next,exception); 2381edb3f510ac6109703f134e42f9a2a0cc21866d78cristy p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception); 238241f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy if (p == (const Quantum *) NULL) 238341f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy { 238441f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy image_view=DestroyCacheView(image_view); 238541f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy break; 238641f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy } 2387edb3f510ac6109703f134e42f9a2a0cc21866d78cristy for (x=0; x < (ssize_t) image->columns; x++) 238841f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy { 238941f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy register ssize_t 239041f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy i; 239141f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy 2392883fde11debec15cedb05dc5d7228d8588066bc0cristy if (GetPixelReadMask(next,p) == 0) 239341f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy { 239441f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy p+=GetPixelChannels(next); 239541f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy continue; 239641f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy } 239741f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy for (i=0; i < (ssize_t) GetPixelChannels(next); i++) 239841f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy { 239941f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy MagickRealType 240041f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy coefficient, 240141f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy degree; 240241f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy 24035a23c55ddcfdf6ae717dd42d8a1c1a2ff8c6305fcristy PixelChannel channel=GetPixelChannelChannel(image,i); 24045a23c55ddcfdf6ae717dd42d8a1c1a2ff8c6305fcristy PixelTrait traits=GetPixelChannelTraits(next,channel); 24055a23c55ddcfdf6ae717dd42d8a1c1a2ff8c6305fcristy PixelTrait polynomial_traits=GetPixelChannelTraits(image,channel); 240641f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy if ((traits == UndefinedPixelTrait) || 240741f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy (polynomial_traits == UndefinedPixelTrait)) 240841f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy continue; 240941f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy if ((traits & UpdatePixelTrait) == 0) 241041f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy continue; 24114a2059693f03167d5ee07470a38c2bdaa4e3688acristy coefficient=(MagickRealType) terms[2*j]; 24124a2059693f03167d5ee07470a38c2bdaa4e3688acristy degree=(MagickRealType) terms[(j << 1)+1]; 241341f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy polynomial_pixel[x].channel[i]+=coefficient* 2414cef3b9988777b669bc008f2ce876c1bacf22e333cristy pow(QuantumScale*GetPixelChannel(image,channel,p),degree); 241541f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy } 241641f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy p+=GetPixelChannels(next); 241741f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy } 241841f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy image_view=DestroyCacheView(image_view); 241941f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy next=GetNextImageInList(next); 242041f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy } 242141f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy for (x=0; x < (ssize_t) image->columns; x++) 242241f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy { 242341f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy register ssize_t 242441f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy i; 242541f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy 2426883fde11debec15cedb05dc5d7228d8588066bc0cristy if (GetPixelReadMask(image,q) == 0) 242741f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy { 242841f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy q+=GetPixelChannels(image); 242941f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy continue; 243041f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy } 243141f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy for (i=0; i < (ssize_t) GetPixelChannels(image); i++) 243241f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy { 24335a23c55ddcfdf6ae717dd42d8a1c1a2ff8c6305fcristy PixelChannel channel=GetPixelChannelChannel(image,i); 24345a23c55ddcfdf6ae717dd42d8a1c1a2ff8c6305fcristy PixelTrait traits=GetPixelChannelTraits(image,channel); 243541f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy if (traits == UndefinedPixelTrait) 243641f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy continue; 243741f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy if ((traits & UpdatePixelTrait) == 0) 243841f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy continue; 2439cef3b9988777b669bc008f2ce876c1bacf22e333cristy q[i]=ClampToQuantum(QuantumRange*polynomial_pixel[x].channel[i]); 244041f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy } 244141f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy q+=GetPixelChannels(image); 244241f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy } 244341f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy if (SyncCacheViewAuthenticPixels(polynomial_view,exception) == MagickFalse) 244441f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy status=MagickFalse; 244541f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy if (images->progress_monitor != (MagickProgressMonitor) NULL) 244641f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy { 244741f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy MagickBooleanType 244841f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy proceed; 244941f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy 245041f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy#if defined(MAGICKCORE_OPENMP_SUPPORT) 245141f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy #pragma omp critical (MagickCore_PolynomialImages) 245241f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy#endif 245341f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy proceed=SetImageProgress(images,PolynomialImageTag,progress++, 245441f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy image->rows); 245541f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy if (proceed == MagickFalse) 245641f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy status=MagickFalse; 245741f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy } 245841f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy } 245941f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy polynomial_view=DestroyCacheView(polynomial_view); 246041f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy polynomial_pixels=DestroyPixelThreadSet(polynomial_pixels); 246141f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy if (status == MagickFalse) 246241f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy image=DestroyImage(image); 246341f5fe9f39b5f0d7d8be74eaed6e5358888c6f1bcristy return(image); 2464f56e6ad6da167beca48fb23194201c25cd3dfb8ecristy} 2465f56e6ad6da167beca48fb23194201c25cd3dfb8ecristy 2466f56e6ad6da167beca48fb23194201c25cd3dfb8ecristy/* 2467f56e6ad6da167beca48fb23194201c25cd3dfb8ecristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2468f56e6ad6da167beca48fb23194201c25cd3dfb8ecristy% % 2469f56e6ad6da167beca48fb23194201c25cd3dfb8ecristy% % 247099bd523143cfe6d0407e260adf99d7384c30532dcristy% % 247199bd523143cfe6d0407e260adf99d7384c30532dcristy% S t a t i s t i c I m a g e % 247299bd523143cfe6d0407e260adf99d7384c30532dcristy% % 247399bd523143cfe6d0407e260adf99d7384c30532dcristy% % 247499bd523143cfe6d0407e260adf99d7384c30532dcristy% % 247599bd523143cfe6d0407e260adf99d7384c30532dcristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 247699bd523143cfe6d0407e260adf99d7384c30532dcristy% 247799bd523143cfe6d0407e260adf99d7384c30532dcristy% StatisticImage() makes each pixel the min / max / median / mode / etc. of 247899bd523143cfe6d0407e260adf99d7384c30532dcristy% the neighborhood of the specified width and height. 247999bd523143cfe6d0407e260adf99d7384c30532dcristy% 248099bd523143cfe6d0407e260adf99d7384c30532dcristy% The format of the StatisticImage method is: 248199bd523143cfe6d0407e260adf99d7384c30532dcristy% 248299bd523143cfe6d0407e260adf99d7384c30532dcristy% Image *StatisticImage(const Image *image,const StatisticType type, 248399bd523143cfe6d0407e260adf99d7384c30532dcristy% const size_t width,const size_t height,ExceptionInfo *exception) 248499bd523143cfe6d0407e260adf99d7384c30532dcristy% 248599bd523143cfe6d0407e260adf99d7384c30532dcristy% A description of each parameter follows: 248699bd523143cfe6d0407e260adf99d7384c30532dcristy% 248799bd523143cfe6d0407e260adf99d7384c30532dcristy% o image: the image. 248899bd523143cfe6d0407e260adf99d7384c30532dcristy% 248999bd523143cfe6d0407e260adf99d7384c30532dcristy% o type: the statistic type (median, mode, etc.). 249099bd523143cfe6d0407e260adf99d7384c30532dcristy% 249199bd523143cfe6d0407e260adf99d7384c30532dcristy% o width: the width of the pixel neighborhood. 249299bd523143cfe6d0407e260adf99d7384c30532dcristy% 249399bd523143cfe6d0407e260adf99d7384c30532dcristy% o height: the height of the pixel neighborhood. 249499bd523143cfe6d0407e260adf99d7384c30532dcristy% 249599bd523143cfe6d0407e260adf99d7384c30532dcristy% o exception: return any errors or warnings in this structure. 249699bd523143cfe6d0407e260adf99d7384c30532dcristy% 249799bd523143cfe6d0407e260adf99d7384c30532dcristy*/ 249899bd523143cfe6d0407e260adf99d7384c30532dcristy 249999bd523143cfe6d0407e260adf99d7384c30532dcristytypedef struct _SkipNode 250099bd523143cfe6d0407e260adf99d7384c30532dcristy{ 250199bd523143cfe6d0407e260adf99d7384c30532dcristy size_t 250299bd523143cfe6d0407e260adf99d7384c30532dcristy next[9], 250399bd523143cfe6d0407e260adf99d7384c30532dcristy count, 250499bd523143cfe6d0407e260adf99d7384c30532dcristy signature; 250599bd523143cfe6d0407e260adf99d7384c30532dcristy} SkipNode; 250699bd523143cfe6d0407e260adf99d7384c30532dcristy 250799bd523143cfe6d0407e260adf99d7384c30532dcristytypedef struct _SkipList 250899bd523143cfe6d0407e260adf99d7384c30532dcristy{ 250999bd523143cfe6d0407e260adf99d7384c30532dcristy ssize_t 251099bd523143cfe6d0407e260adf99d7384c30532dcristy level; 251199bd523143cfe6d0407e260adf99d7384c30532dcristy 251299bd523143cfe6d0407e260adf99d7384c30532dcristy SkipNode 251399bd523143cfe6d0407e260adf99d7384c30532dcristy *nodes; 251499bd523143cfe6d0407e260adf99d7384c30532dcristy} SkipList; 251599bd523143cfe6d0407e260adf99d7384c30532dcristy 251699bd523143cfe6d0407e260adf99d7384c30532dcristytypedef struct _PixelList 251799bd523143cfe6d0407e260adf99d7384c30532dcristy{ 251899bd523143cfe6d0407e260adf99d7384c30532dcristy size_t 251999bd523143cfe6d0407e260adf99d7384c30532dcristy length, 252099bd523143cfe6d0407e260adf99d7384c30532dcristy seed; 252199bd523143cfe6d0407e260adf99d7384c30532dcristy 252299bd523143cfe6d0407e260adf99d7384c30532dcristy SkipList 252399bd523143cfe6d0407e260adf99d7384c30532dcristy skip_list; 252499bd523143cfe6d0407e260adf99d7384c30532dcristy 252599bd523143cfe6d0407e260adf99d7384c30532dcristy size_t 252699bd523143cfe6d0407e260adf99d7384c30532dcristy signature; 252799bd523143cfe6d0407e260adf99d7384c30532dcristy} PixelList; 252899bd523143cfe6d0407e260adf99d7384c30532dcristy 252999bd523143cfe6d0407e260adf99d7384c30532dcristystatic PixelList *DestroyPixelList(PixelList *pixel_list) 253099bd523143cfe6d0407e260adf99d7384c30532dcristy{ 253199bd523143cfe6d0407e260adf99d7384c30532dcristy if (pixel_list == (PixelList *) NULL) 253299bd523143cfe6d0407e260adf99d7384c30532dcristy return((PixelList *) NULL); 253399bd523143cfe6d0407e260adf99d7384c30532dcristy if (pixel_list->skip_list.nodes != (SkipNode *) NULL) 253499bd523143cfe6d0407e260adf99d7384c30532dcristy pixel_list->skip_list.nodes=(SkipNode *) RelinquishMagickMemory( 253599bd523143cfe6d0407e260adf99d7384c30532dcristy pixel_list->skip_list.nodes); 253699bd523143cfe6d0407e260adf99d7384c30532dcristy pixel_list=(PixelList *) RelinquishMagickMemory(pixel_list); 253799bd523143cfe6d0407e260adf99d7384c30532dcristy return(pixel_list); 253899bd523143cfe6d0407e260adf99d7384c30532dcristy} 253999bd523143cfe6d0407e260adf99d7384c30532dcristy 254099bd523143cfe6d0407e260adf99d7384c30532dcristystatic PixelList **DestroyPixelListThreadSet(PixelList **pixel_list) 254199bd523143cfe6d0407e260adf99d7384c30532dcristy{ 254299bd523143cfe6d0407e260adf99d7384c30532dcristy register ssize_t 254399bd523143cfe6d0407e260adf99d7384c30532dcristy i; 254499bd523143cfe6d0407e260adf99d7384c30532dcristy 254599bd523143cfe6d0407e260adf99d7384c30532dcristy assert(pixel_list != (PixelList **) NULL); 2546ac245f8a51ea65b085d751c41d8ca4b426bdfe5bcristy for (i=0; i < (ssize_t) GetMagickResourceLimit(ThreadResource); i++) 254799bd523143cfe6d0407e260adf99d7384c30532dcristy if (pixel_list[i] != (PixelList *) NULL) 254899bd523143cfe6d0407e260adf99d7384c30532dcristy pixel_list[i]=DestroyPixelList(pixel_list[i]); 254999bd523143cfe6d0407e260adf99d7384c30532dcristy pixel_list=(PixelList **) RelinquishMagickMemory(pixel_list); 255099bd523143cfe6d0407e260adf99d7384c30532dcristy return(pixel_list); 255199bd523143cfe6d0407e260adf99d7384c30532dcristy} 255299bd523143cfe6d0407e260adf99d7384c30532dcristy 255399bd523143cfe6d0407e260adf99d7384c30532dcristystatic PixelList *AcquirePixelList(const size_t width,const size_t height) 255499bd523143cfe6d0407e260adf99d7384c30532dcristy{ 255599bd523143cfe6d0407e260adf99d7384c30532dcristy PixelList 255699bd523143cfe6d0407e260adf99d7384c30532dcristy *pixel_list; 255799bd523143cfe6d0407e260adf99d7384c30532dcristy 255899bd523143cfe6d0407e260adf99d7384c30532dcristy pixel_list=(PixelList *) AcquireMagickMemory(sizeof(*pixel_list)); 255999bd523143cfe6d0407e260adf99d7384c30532dcristy if (pixel_list == (PixelList *) NULL) 256099bd523143cfe6d0407e260adf99d7384c30532dcristy return(pixel_list); 256199bd523143cfe6d0407e260adf99d7384c30532dcristy (void) ResetMagickMemory((void *) pixel_list,0,sizeof(*pixel_list)); 256299bd523143cfe6d0407e260adf99d7384c30532dcristy pixel_list->length=width*height; 256399bd523143cfe6d0407e260adf99d7384c30532dcristy pixel_list->skip_list.nodes=(SkipNode *) AcquireQuantumMemory(65537UL, 256499bd523143cfe6d0407e260adf99d7384c30532dcristy sizeof(*pixel_list->skip_list.nodes)); 256599bd523143cfe6d0407e260adf99d7384c30532dcristy if (pixel_list->skip_list.nodes == (SkipNode *) NULL) 256699bd523143cfe6d0407e260adf99d7384c30532dcristy return(DestroyPixelList(pixel_list)); 256799bd523143cfe6d0407e260adf99d7384c30532dcristy (void) ResetMagickMemory(pixel_list->skip_list.nodes,0,65537UL* 256899bd523143cfe6d0407e260adf99d7384c30532dcristy sizeof(*pixel_list->skip_list.nodes)); 2569e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy pixel_list->signature=MagickCoreSignature; 257099bd523143cfe6d0407e260adf99d7384c30532dcristy return(pixel_list); 257199bd523143cfe6d0407e260adf99d7384c30532dcristy} 257299bd523143cfe6d0407e260adf99d7384c30532dcristy 257399bd523143cfe6d0407e260adf99d7384c30532dcristystatic PixelList **AcquirePixelListThreadSet(const size_t width, 257499bd523143cfe6d0407e260adf99d7384c30532dcristy const size_t height) 257599bd523143cfe6d0407e260adf99d7384c30532dcristy{ 257699bd523143cfe6d0407e260adf99d7384c30532dcristy PixelList 257799bd523143cfe6d0407e260adf99d7384c30532dcristy **pixel_list; 257899bd523143cfe6d0407e260adf99d7384c30532dcristy 257999bd523143cfe6d0407e260adf99d7384c30532dcristy register ssize_t 258099bd523143cfe6d0407e260adf99d7384c30532dcristy i; 258199bd523143cfe6d0407e260adf99d7384c30532dcristy 258299bd523143cfe6d0407e260adf99d7384c30532dcristy size_t 258399bd523143cfe6d0407e260adf99d7384c30532dcristy number_threads; 258499bd523143cfe6d0407e260adf99d7384c30532dcristy 25859357bdd9a30c3d65ef8812e45220f7552dc4376bcristy number_threads=(size_t) GetMagickResourceLimit(ThreadResource); 258699bd523143cfe6d0407e260adf99d7384c30532dcristy pixel_list=(PixelList **) AcquireQuantumMemory(number_threads, 258799bd523143cfe6d0407e260adf99d7384c30532dcristy sizeof(*pixel_list)); 258899bd523143cfe6d0407e260adf99d7384c30532dcristy if (pixel_list == (PixelList **) NULL) 258999bd523143cfe6d0407e260adf99d7384c30532dcristy return((PixelList **) NULL); 259099bd523143cfe6d0407e260adf99d7384c30532dcristy (void) ResetMagickMemory(pixel_list,0,number_threads*sizeof(*pixel_list)); 259199bd523143cfe6d0407e260adf99d7384c30532dcristy for (i=0; i < (ssize_t) number_threads; i++) 259299bd523143cfe6d0407e260adf99d7384c30532dcristy { 259399bd523143cfe6d0407e260adf99d7384c30532dcristy pixel_list[i]=AcquirePixelList(width,height); 259499bd523143cfe6d0407e260adf99d7384c30532dcristy if (pixel_list[i] == (PixelList *) NULL) 259599bd523143cfe6d0407e260adf99d7384c30532dcristy return(DestroyPixelListThreadSet(pixel_list)); 259699bd523143cfe6d0407e260adf99d7384c30532dcristy } 259799bd523143cfe6d0407e260adf99d7384c30532dcristy return(pixel_list); 259899bd523143cfe6d0407e260adf99d7384c30532dcristy} 259999bd523143cfe6d0407e260adf99d7384c30532dcristy 260099bd523143cfe6d0407e260adf99d7384c30532dcristystatic void AddNodePixelList(PixelList *pixel_list,const size_t color) 260199bd523143cfe6d0407e260adf99d7384c30532dcristy{ 260299bd523143cfe6d0407e260adf99d7384c30532dcristy register SkipList 260399bd523143cfe6d0407e260adf99d7384c30532dcristy *p; 260499bd523143cfe6d0407e260adf99d7384c30532dcristy 260599bd523143cfe6d0407e260adf99d7384c30532dcristy register ssize_t 260699bd523143cfe6d0407e260adf99d7384c30532dcristy level; 260799bd523143cfe6d0407e260adf99d7384c30532dcristy 260899bd523143cfe6d0407e260adf99d7384c30532dcristy size_t 260999bd523143cfe6d0407e260adf99d7384c30532dcristy search, 261099bd523143cfe6d0407e260adf99d7384c30532dcristy update[9]; 261199bd523143cfe6d0407e260adf99d7384c30532dcristy 261299bd523143cfe6d0407e260adf99d7384c30532dcristy /* 261399bd523143cfe6d0407e260adf99d7384c30532dcristy Initialize the node. 261499bd523143cfe6d0407e260adf99d7384c30532dcristy */ 261599bd523143cfe6d0407e260adf99d7384c30532dcristy p=(&pixel_list->skip_list); 261699bd523143cfe6d0407e260adf99d7384c30532dcristy p->nodes[color].signature=pixel_list->signature; 261799bd523143cfe6d0407e260adf99d7384c30532dcristy p->nodes[color].count=1; 261899bd523143cfe6d0407e260adf99d7384c30532dcristy /* 261999bd523143cfe6d0407e260adf99d7384c30532dcristy Determine where it belongs in the list. 262099bd523143cfe6d0407e260adf99d7384c30532dcristy */ 262199bd523143cfe6d0407e260adf99d7384c30532dcristy search=65536UL; 262299bd523143cfe6d0407e260adf99d7384c30532dcristy for (level=p->level; level >= 0; level--) 262399bd523143cfe6d0407e260adf99d7384c30532dcristy { 262499bd523143cfe6d0407e260adf99d7384c30532dcristy while (p->nodes[search].next[level] < color) 262599bd523143cfe6d0407e260adf99d7384c30532dcristy search=p->nodes[search].next[level]; 262699bd523143cfe6d0407e260adf99d7384c30532dcristy update[level]=search; 262799bd523143cfe6d0407e260adf99d7384c30532dcristy } 262899bd523143cfe6d0407e260adf99d7384c30532dcristy /* 262999bd523143cfe6d0407e260adf99d7384c30532dcristy Generate a pseudo-random level for this node. 263099bd523143cfe6d0407e260adf99d7384c30532dcristy */ 263199bd523143cfe6d0407e260adf99d7384c30532dcristy for (level=0; ; level++) 263299bd523143cfe6d0407e260adf99d7384c30532dcristy { 263399bd523143cfe6d0407e260adf99d7384c30532dcristy pixel_list->seed=(pixel_list->seed*42893621L)+1L; 263499bd523143cfe6d0407e260adf99d7384c30532dcristy if ((pixel_list->seed & 0x300) != 0x300) 263599bd523143cfe6d0407e260adf99d7384c30532dcristy break; 263699bd523143cfe6d0407e260adf99d7384c30532dcristy } 263799bd523143cfe6d0407e260adf99d7384c30532dcristy if (level > 8) 263899bd523143cfe6d0407e260adf99d7384c30532dcristy level=8; 263999bd523143cfe6d0407e260adf99d7384c30532dcristy if (level > (p->level+2)) 264099bd523143cfe6d0407e260adf99d7384c30532dcristy level=p->level+2; 264199bd523143cfe6d0407e260adf99d7384c30532dcristy /* 264299bd523143cfe6d0407e260adf99d7384c30532dcristy If we're raising the list's level, link back to the root node. 264399bd523143cfe6d0407e260adf99d7384c30532dcristy */ 264499bd523143cfe6d0407e260adf99d7384c30532dcristy while (level > p->level) 264599bd523143cfe6d0407e260adf99d7384c30532dcristy { 264699bd523143cfe6d0407e260adf99d7384c30532dcristy p->level++; 264799bd523143cfe6d0407e260adf99d7384c30532dcristy update[p->level]=65536UL; 264899bd523143cfe6d0407e260adf99d7384c30532dcristy } 264999bd523143cfe6d0407e260adf99d7384c30532dcristy /* 265099bd523143cfe6d0407e260adf99d7384c30532dcristy Link the node into the skip-list. 265199bd523143cfe6d0407e260adf99d7384c30532dcristy */ 265299bd523143cfe6d0407e260adf99d7384c30532dcristy do 265399bd523143cfe6d0407e260adf99d7384c30532dcristy { 265499bd523143cfe6d0407e260adf99d7384c30532dcristy p->nodes[color].next[level]=p->nodes[update[level]].next[level]; 265599bd523143cfe6d0407e260adf99d7384c30532dcristy p->nodes[update[level]].next[level]=color; 265699bd523143cfe6d0407e260adf99d7384c30532dcristy } while (level-- > 0); 265799bd523143cfe6d0407e260adf99d7384c30532dcristy} 265899bd523143cfe6d0407e260adf99d7384c30532dcristy 265999bd523143cfe6d0407e260adf99d7384c30532dcristystatic inline void GetMaximumPixelList(PixelList *pixel_list,Quantum *pixel) 266099bd523143cfe6d0407e260adf99d7384c30532dcristy{ 266199bd523143cfe6d0407e260adf99d7384c30532dcristy register SkipList 266299bd523143cfe6d0407e260adf99d7384c30532dcristy *p; 266399bd523143cfe6d0407e260adf99d7384c30532dcristy 266499bd523143cfe6d0407e260adf99d7384c30532dcristy size_t 266599bd523143cfe6d0407e260adf99d7384c30532dcristy color, 266699bd523143cfe6d0407e260adf99d7384c30532dcristy maximum; 266799bd523143cfe6d0407e260adf99d7384c30532dcristy 266899bd523143cfe6d0407e260adf99d7384c30532dcristy ssize_t 266999bd523143cfe6d0407e260adf99d7384c30532dcristy count; 267099bd523143cfe6d0407e260adf99d7384c30532dcristy 267199bd523143cfe6d0407e260adf99d7384c30532dcristy /* 267299bd523143cfe6d0407e260adf99d7384c30532dcristy Find the maximum value for each of the color. 267399bd523143cfe6d0407e260adf99d7384c30532dcristy */ 267499bd523143cfe6d0407e260adf99d7384c30532dcristy p=(&pixel_list->skip_list); 267599bd523143cfe6d0407e260adf99d7384c30532dcristy color=65536L; 267699bd523143cfe6d0407e260adf99d7384c30532dcristy count=0; 267799bd523143cfe6d0407e260adf99d7384c30532dcristy maximum=p->nodes[color].next[0]; 267899bd523143cfe6d0407e260adf99d7384c30532dcristy do 267999bd523143cfe6d0407e260adf99d7384c30532dcristy { 268099bd523143cfe6d0407e260adf99d7384c30532dcristy color=p->nodes[color].next[0]; 268199bd523143cfe6d0407e260adf99d7384c30532dcristy if (color > maximum) 268299bd523143cfe6d0407e260adf99d7384c30532dcristy maximum=color; 268399bd523143cfe6d0407e260adf99d7384c30532dcristy count+=p->nodes[color].count; 268499bd523143cfe6d0407e260adf99d7384c30532dcristy } while (count < (ssize_t) pixel_list->length); 268599bd523143cfe6d0407e260adf99d7384c30532dcristy *pixel=ScaleShortToQuantum((unsigned short) maximum); 268699bd523143cfe6d0407e260adf99d7384c30532dcristy} 268799bd523143cfe6d0407e260adf99d7384c30532dcristy 268899bd523143cfe6d0407e260adf99d7384c30532dcristystatic inline void GetMeanPixelList(PixelList *pixel_list,Quantum *pixel) 268999bd523143cfe6d0407e260adf99d7384c30532dcristy{ 2690a19f1d70e9a9f88279c4ecafe6dfafc1f9a09599cristy double 269199bd523143cfe6d0407e260adf99d7384c30532dcristy sum; 269299bd523143cfe6d0407e260adf99d7384c30532dcristy 269399bd523143cfe6d0407e260adf99d7384c30532dcristy register SkipList 269499bd523143cfe6d0407e260adf99d7384c30532dcristy *p; 269599bd523143cfe6d0407e260adf99d7384c30532dcristy 269699bd523143cfe6d0407e260adf99d7384c30532dcristy size_t 269799bd523143cfe6d0407e260adf99d7384c30532dcristy color; 269899bd523143cfe6d0407e260adf99d7384c30532dcristy 269999bd523143cfe6d0407e260adf99d7384c30532dcristy ssize_t 270099bd523143cfe6d0407e260adf99d7384c30532dcristy count; 270199bd523143cfe6d0407e260adf99d7384c30532dcristy 270299bd523143cfe6d0407e260adf99d7384c30532dcristy /* 270399bd523143cfe6d0407e260adf99d7384c30532dcristy Find the mean value for each of the color. 270499bd523143cfe6d0407e260adf99d7384c30532dcristy */ 270599bd523143cfe6d0407e260adf99d7384c30532dcristy p=(&pixel_list->skip_list); 270699bd523143cfe6d0407e260adf99d7384c30532dcristy color=65536L; 270799bd523143cfe6d0407e260adf99d7384c30532dcristy count=0; 270899bd523143cfe6d0407e260adf99d7384c30532dcristy sum=0.0; 270999bd523143cfe6d0407e260adf99d7384c30532dcristy do 271099bd523143cfe6d0407e260adf99d7384c30532dcristy { 271199bd523143cfe6d0407e260adf99d7384c30532dcristy color=p->nodes[color].next[0]; 2712a19f1d70e9a9f88279c4ecafe6dfafc1f9a09599cristy sum+=(double) p->nodes[color].count*color; 271399bd523143cfe6d0407e260adf99d7384c30532dcristy count+=p->nodes[color].count; 271499bd523143cfe6d0407e260adf99d7384c30532dcristy } while (count < (ssize_t) pixel_list->length); 271599bd523143cfe6d0407e260adf99d7384c30532dcristy sum/=pixel_list->length; 271699bd523143cfe6d0407e260adf99d7384c30532dcristy *pixel=ScaleShortToQuantum((unsigned short) sum); 271799bd523143cfe6d0407e260adf99d7384c30532dcristy} 271899bd523143cfe6d0407e260adf99d7384c30532dcristy 271999bd523143cfe6d0407e260adf99d7384c30532dcristystatic inline void GetMedianPixelList(PixelList *pixel_list,Quantum *pixel) 272099bd523143cfe6d0407e260adf99d7384c30532dcristy{ 272199bd523143cfe6d0407e260adf99d7384c30532dcristy register SkipList 272299bd523143cfe6d0407e260adf99d7384c30532dcristy *p; 272399bd523143cfe6d0407e260adf99d7384c30532dcristy 272499bd523143cfe6d0407e260adf99d7384c30532dcristy size_t 272599bd523143cfe6d0407e260adf99d7384c30532dcristy color; 272699bd523143cfe6d0407e260adf99d7384c30532dcristy 272799bd523143cfe6d0407e260adf99d7384c30532dcristy ssize_t 272899bd523143cfe6d0407e260adf99d7384c30532dcristy count; 272999bd523143cfe6d0407e260adf99d7384c30532dcristy 273099bd523143cfe6d0407e260adf99d7384c30532dcristy /* 273199bd523143cfe6d0407e260adf99d7384c30532dcristy Find the median value for each of the color. 273299bd523143cfe6d0407e260adf99d7384c30532dcristy */ 273399bd523143cfe6d0407e260adf99d7384c30532dcristy p=(&pixel_list->skip_list); 273499bd523143cfe6d0407e260adf99d7384c30532dcristy color=65536L; 273599bd523143cfe6d0407e260adf99d7384c30532dcristy count=0; 273699bd523143cfe6d0407e260adf99d7384c30532dcristy do 273799bd523143cfe6d0407e260adf99d7384c30532dcristy { 273899bd523143cfe6d0407e260adf99d7384c30532dcristy color=p->nodes[color].next[0]; 273999bd523143cfe6d0407e260adf99d7384c30532dcristy count+=p->nodes[color].count; 274099bd523143cfe6d0407e260adf99d7384c30532dcristy } while (count <= (ssize_t) (pixel_list->length >> 1)); 274199bd523143cfe6d0407e260adf99d7384c30532dcristy *pixel=ScaleShortToQuantum((unsigned short) color); 274299bd523143cfe6d0407e260adf99d7384c30532dcristy} 274399bd523143cfe6d0407e260adf99d7384c30532dcristy 274499bd523143cfe6d0407e260adf99d7384c30532dcristystatic inline void GetMinimumPixelList(PixelList *pixel_list,Quantum *pixel) 274599bd523143cfe6d0407e260adf99d7384c30532dcristy{ 274699bd523143cfe6d0407e260adf99d7384c30532dcristy register SkipList 274799bd523143cfe6d0407e260adf99d7384c30532dcristy *p; 274899bd523143cfe6d0407e260adf99d7384c30532dcristy 274999bd523143cfe6d0407e260adf99d7384c30532dcristy size_t 275099bd523143cfe6d0407e260adf99d7384c30532dcristy color, 275199bd523143cfe6d0407e260adf99d7384c30532dcristy minimum; 275299bd523143cfe6d0407e260adf99d7384c30532dcristy 275399bd523143cfe6d0407e260adf99d7384c30532dcristy ssize_t 275499bd523143cfe6d0407e260adf99d7384c30532dcristy count; 275599bd523143cfe6d0407e260adf99d7384c30532dcristy 275699bd523143cfe6d0407e260adf99d7384c30532dcristy /* 275799bd523143cfe6d0407e260adf99d7384c30532dcristy Find the minimum value for each of the color. 275899bd523143cfe6d0407e260adf99d7384c30532dcristy */ 275999bd523143cfe6d0407e260adf99d7384c30532dcristy p=(&pixel_list->skip_list); 276099bd523143cfe6d0407e260adf99d7384c30532dcristy count=0; 276199bd523143cfe6d0407e260adf99d7384c30532dcristy color=65536UL; 276299bd523143cfe6d0407e260adf99d7384c30532dcristy minimum=p->nodes[color].next[0]; 276399bd523143cfe6d0407e260adf99d7384c30532dcristy do 276499bd523143cfe6d0407e260adf99d7384c30532dcristy { 276599bd523143cfe6d0407e260adf99d7384c30532dcristy color=p->nodes[color].next[0]; 276699bd523143cfe6d0407e260adf99d7384c30532dcristy if (color < minimum) 276799bd523143cfe6d0407e260adf99d7384c30532dcristy minimum=color; 276899bd523143cfe6d0407e260adf99d7384c30532dcristy count+=p->nodes[color].count; 276999bd523143cfe6d0407e260adf99d7384c30532dcristy } while (count < (ssize_t) pixel_list->length); 277099bd523143cfe6d0407e260adf99d7384c30532dcristy *pixel=ScaleShortToQuantum((unsigned short) minimum); 277199bd523143cfe6d0407e260adf99d7384c30532dcristy} 277299bd523143cfe6d0407e260adf99d7384c30532dcristy 277399bd523143cfe6d0407e260adf99d7384c30532dcristystatic inline void GetModePixelList(PixelList *pixel_list,Quantum *pixel) 277499bd523143cfe6d0407e260adf99d7384c30532dcristy{ 277599bd523143cfe6d0407e260adf99d7384c30532dcristy register SkipList 277699bd523143cfe6d0407e260adf99d7384c30532dcristy *p; 277799bd523143cfe6d0407e260adf99d7384c30532dcristy 277899bd523143cfe6d0407e260adf99d7384c30532dcristy size_t 277999bd523143cfe6d0407e260adf99d7384c30532dcristy color, 278099bd523143cfe6d0407e260adf99d7384c30532dcristy max_count, 278199bd523143cfe6d0407e260adf99d7384c30532dcristy mode; 278299bd523143cfe6d0407e260adf99d7384c30532dcristy 278399bd523143cfe6d0407e260adf99d7384c30532dcristy ssize_t 278499bd523143cfe6d0407e260adf99d7384c30532dcristy count; 278599bd523143cfe6d0407e260adf99d7384c30532dcristy 278699bd523143cfe6d0407e260adf99d7384c30532dcristy /* 278799bd523143cfe6d0407e260adf99d7384c30532dcristy Make each pixel the 'predominant color' of the specified neighborhood. 278899bd523143cfe6d0407e260adf99d7384c30532dcristy */ 278999bd523143cfe6d0407e260adf99d7384c30532dcristy p=(&pixel_list->skip_list); 279099bd523143cfe6d0407e260adf99d7384c30532dcristy color=65536L; 279199bd523143cfe6d0407e260adf99d7384c30532dcristy mode=color; 279299bd523143cfe6d0407e260adf99d7384c30532dcristy max_count=p->nodes[mode].count; 279399bd523143cfe6d0407e260adf99d7384c30532dcristy count=0; 279499bd523143cfe6d0407e260adf99d7384c30532dcristy do 279599bd523143cfe6d0407e260adf99d7384c30532dcristy { 279699bd523143cfe6d0407e260adf99d7384c30532dcristy color=p->nodes[color].next[0]; 279799bd523143cfe6d0407e260adf99d7384c30532dcristy if (p->nodes[color].count > max_count) 279899bd523143cfe6d0407e260adf99d7384c30532dcristy { 279999bd523143cfe6d0407e260adf99d7384c30532dcristy mode=color; 280099bd523143cfe6d0407e260adf99d7384c30532dcristy max_count=p->nodes[mode].count; 280199bd523143cfe6d0407e260adf99d7384c30532dcristy } 280299bd523143cfe6d0407e260adf99d7384c30532dcristy count+=p->nodes[color].count; 280399bd523143cfe6d0407e260adf99d7384c30532dcristy } while (count < (ssize_t) pixel_list->length); 280499bd523143cfe6d0407e260adf99d7384c30532dcristy *pixel=ScaleShortToQuantum((unsigned short) mode); 280599bd523143cfe6d0407e260adf99d7384c30532dcristy} 280699bd523143cfe6d0407e260adf99d7384c30532dcristy 280799bd523143cfe6d0407e260adf99d7384c30532dcristystatic inline void GetNonpeakPixelList(PixelList *pixel_list,Quantum *pixel) 280899bd523143cfe6d0407e260adf99d7384c30532dcristy{ 280999bd523143cfe6d0407e260adf99d7384c30532dcristy register SkipList 281099bd523143cfe6d0407e260adf99d7384c30532dcristy *p; 281199bd523143cfe6d0407e260adf99d7384c30532dcristy 281299bd523143cfe6d0407e260adf99d7384c30532dcristy size_t 281399bd523143cfe6d0407e260adf99d7384c30532dcristy color, 281499bd523143cfe6d0407e260adf99d7384c30532dcristy next, 281599bd523143cfe6d0407e260adf99d7384c30532dcristy previous; 281699bd523143cfe6d0407e260adf99d7384c30532dcristy 281799bd523143cfe6d0407e260adf99d7384c30532dcristy ssize_t 281899bd523143cfe6d0407e260adf99d7384c30532dcristy count; 281999bd523143cfe6d0407e260adf99d7384c30532dcristy 282099bd523143cfe6d0407e260adf99d7384c30532dcristy /* 282199bd523143cfe6d0407e260adf99d7384c30532dcristy Finds the non peak value for each of the colors. 282299bd523143cfe6d0407e260adf99d7384c30532dcristy */ 282399bd523143cfe6d0407e260adf99d7384c30532dcristy p=(&pixel_list->skip_list); 282499bd523143cfe6d0407e260adf99d7384c30532dcristy color=65536L; 282599bd523143cfe6d0407e260adf99d7384c30532dcristy next=p->nodes[color].next[0]; 282699bd523143cfe6d0407e260adf99d7384c30532dcristy count=0; 282799bd523143cfe6d0407e260adf99d7384c30532dcristy do 282899bd523143cfe6d0407e260adf99d7384c30532dcristy { 282999bd523143cfe6d0407e260adf99d7384c30532dcristy previous=color; 283099bd523143cfe6d0407e260adf99d7384c30532dcristy color=next; 283199bd523143cfe6d0407e260adf99d7384c30532dcristy next=p->nodes[color].next[0]; 283299bd523143cfe6d0407e260adf99d7384c30532dcristy count+=p->nodes[color].count; 283399bd523143cfe6d0407e260adf99d7384c30532dcristy } while (count <= (ssize_t) (pixel_list->length >> 1)); 283499bd523143cfe6d0407e260adf99d7384c30532dcristy if ((previous == 65536UL) && (next != 65536UL)) 283599bd523143cfe6d0407e260adf99d7384c30532dcristy color=next; 283699bd523143cfe6d0407e260adf99d7384c30532dcristy else 283799bd523143cfe6d0407e260adf99d7384c30532dcristy if ((previous != 65536UL) && (next == 65536UL)) 283899bd523143cfe6d0407e260adf99d7384c30532dcristy color=previous; 283999bd523143cfe6d0407e260adf99d7384c30532dcristy *pixel=ScaleShortToQuantum((unsigned short) color); 284099bd523143cfe6d0407e260adf99d7384c30532dcristy} 284199bd523143cfe6d0407e260adf99d7384c30532dcristy 2842180908c3457893af93b890e3d01a992727574877cristystatic inline void GetRootMeanSquarePixelList(PixelList *pixel_list, 2843180908c3457893af93b890e3d01a992727574877cristy Quantum *pixel) 2844180908c3457893af93b890e3d01a992727574877cristy{ 2845180908c3457893af93b890e3d01a992727574877cristy double 2846180908c3457893af93b890e3d01a992727574877cristy sum; 2847180908c3457893af93b890e3d01a992727574877cristy 2848180908c3457893af93b890e3d01a992727574877cristy register SkipList 2849180908c3457893af93b890e3d01a992727574877cristy *p; 2850180908c3457893af93b890e3d01a992727574877cristy 2851180908c3457893af93b890e3d01a992727574877cristy size_t 2852180908c3457893af93b890e3d01a992727574877cristy color; 2853180908c3457893af93b890e3d01a992727574877cristy 2854180908c3457893af93b890e3d01a992727574877cristy ssize_t 2855180908c3457893af93b890e3d01a992727574877cristy count; 2856180908c3457893af93b890e3d01a992727574877cristy 2857180908c3457893af93b890e3d01a992727574877cristy /* 2858f6841eb57b1dd6793ceed3d28dba80e999d35dc4cristy Find the root mean square value for each of the color. 2859180908c3457893af93b890e3d01a992727574877cristy */ 2860180908c3457893af93b890e3d01a992727574877cristy p=(&pixel_list->skip_list); 2861180908c3457893af93b890e3d01a992727574877cristy color=65536L; 2862180908c3457893af93b890e3d01a992727574877cristy count=0; 2863180908c3457893af93b890e3d01a992727574877cristy sum=0.0; 2864180908c3457893af93b890e3d01a992727574877cristy do 2865180908c3457893af93b890e3d01a992727574877cristy { 2866180908c3457893af93b890e3d01a992727574877cristy color=p->nodes[color].next[0]; 28671db95d8518770b18cb8a69f5c3d3366843c3064fcristy sum+=(double) (p->nodes[color].count*color*color); 2868180908c3457893af93b890e3d01a992727574877cristy count+=p->nodes[color].count; 2869180908c3457893af93b890e3d01a992727574877cristy } while (count < (ssize_t) pixel_list->length); 2870180908c3457893af93b890e3d01a992727574877cristy sum/=pixel_list->length; 2871180908c3457893af93b890e3d01a992727574877cristy *pixel=ScaleShortToQuantum((unsigned short) sqrt(sum)); 2872180908c3457893af93b890e3d01a992727574877cristy} 2873180908c3457893af93b890e3d01a992727574877cristy 287499bd523143cfe6d0407e260adf99d7384c30532dcristystatic inline void GetStandardDeviationPixelList(PixelList *pixel_list, 287599bd523143cfe6d0407e260adf99d7384c30532dcristy Quantum *pixel) 287699bd523143cfe6d0407e260adf99d7384c30532dcristy{ 2877a19f1d70e9a9f88279c4ecafe6dfafc1f9a09599cristy double 287899bd523143cfe6d0407e260adf99d7384c30532dcristy sum, 287999bd523143cfe6d0407e260adf99d7384c30532dcristy sum_squared; 288099bd523143cfe6d0407e260adf99d7384c30532dcristy 288199bd523143cfe6d0407e260adf99d7384c30532dcristy register SkipList 288299bd523143cfe6d0407e260adf99d7384c30532dcristy *p; 288399bd523143cfe6d0407e260adf99d7384c30532dcristy 288499bd523143cfe6d0407e260adf99d7384c30532dcristy size_t 288599bd523143cfe6d0407e260adf99d7384c30532dcristy color; 288699bd523143cfe6d0407e260adf99d7384c30532dcristy 288799bd523143cfe6d0407e260adf99d7384c30532dcristy ssize_t 288899bd523143cfe6d0407e260adf99d7384c30532dcristy count; 288999bd523143cfe6d0407e260adf99d7384c30532dcristy 289099bd523143cfe6d0407e260adf99d7384c30532dcristy /* 289199bd523143cfe6d0407e260adf99d7384c30532dcristy Find the standard-deviation value for each of the color. 289299bd523143cfe6d0407e260adf99d7384c30532dcristy */ 289399bd523143cfe6d0407e260adf99d7384c30532dcristy p=(&pixel_list->skip_list); 289499bd523143cfe6d0407e260adf99d7384c30532dcristy color=65536L; 289599bd523143cfe6d0407e260adf99d7384c30532dcristy count=0; 289699bd523143cfe6d0407e260adf99d7384c30532dcristy sum=0.0; 289799bd523143cfe6d0407e260adf99d7384c30532dcristy sum_squared=0.0; 289899bd523143cfe6d0407e260adf99d7384c30532dcristy do 289999bd523143cfe6d0407e260adf99d7384c30532dcristy { 290099bd523143cfe6d0407e260adf99d7384c30532dcristy register ssize_t 290199bd523143cfe6d0407e260adf99d7384c30532dcristy i; 290299bd523143cfe6d0407e260adf99d7384c30532dcristy 290399bd523143cfe6d0407e260adf99d7384c30532dcristy color=p->nodes[color].next[0]; 2904a19f1d70e9a9f88279c4ecafe6dfafc1f9a09599cristy sum+=(double) p->nodes[color].count*color; 290599bd523143cfe6d0407e260adf99d7384c30532dcristy for (i=0; i < (ssize_t) p->nodes[color].count; i++) 2906a19f1d70e9a9f88279c4ecafe6dfafc1f9a09599cristy sum_squared+=((double) color)*((double) color); 290799bd523143cfe6d0407e260adf99d7384c30532dcristy count+=p->nodes[color].count; 290899bd523143cfe6d0407e260adf99d7384c30532dcristy } while (count < (ssize_t) pixel_list->length); 290999bd523143cfe6d0407e260adf99d7384c30532dcristy sum/=pixel_list->length; 291099bd523143cfe6d0407e260adf99d7384c30532dcristy sum_squared/=pixel_list->length; 291199bd523143cfe6d0407e260adf99d7384c30532dcristy *pixel=ScaleShortToQuantum((unsigned short) sqrt(sum_squared-(sum*sum))); 291299bd523143cfe6d0407e260adf99d7384c30532dcristy} 291399bd523143cfe6d0407e260adf99d7384c30532dcristy 2914b0de93fdedaac769cb08e15b3ec176d4c9078907cristystatic inline void InsertPixelList(const Quantum pixel,PixelList *pixel_list) 291599bd523143cfe6d0407e260adf99d7384c30532dcristy{ 291699bd523143cfe6d0407e260adf99d7384c30532dcristy size_t 291799bd523143cfe6d0407e260adf99d7384c30532dcristy signature; 291899bd523143cfe6d0407e260adf99d7384c30532dcristy 291999bd523143cfe6d0407e260adf99d7384c30532dcristy unsigned short 292099bd523143cfe6d0407e260adf99d7384c30532dcristy index; 292199bd523143cfe6d0407e260adf99d7384c30532dcristy 292299bd523143cfe6d0407e260adf99d7384c30532dcristy index=ScaleQuantumToShort(pixel); 292399bd523143cfe6d0407e260adf99d7384c30532dcristy signature=pixel_list->skip_list.nodes[index].signature; 292499bd523143cfe6d0407e260adf99d7384c30532dcristy if (signature == pixel_list->signature) 292599bd523143cfe6d0407e260adf99d7384c30532dcristy { 292699bd523143cfe6d0407e260adf99d7384c30532dcristy pixel_list->skip_list.nodes[index].count++; 292799bd523143cfe6d0407e260adf99d7384c30532dcristy return; 292899bd523143cfe6d0407e260adf99d7384c30532dcristy } 292999bd523143cfe6d0407e260adf99d7384c30532dcristy AddNodePixelList(pixel_list,index); 293099bd523143cfe6d0407e260adf99d7384c30532dcristy} 293199bd523143cfe6d0407e260adf99d7384c30532dcristy 293299bd523143cfe6d0407e260adf99d7384c30532dcristystatic void ResetPixelList(PixelList *pixel_list) 293399bd523143cfe6d0407e260adf99d7384c30532dcristy{ 293499bd523143cfe6d0407e260adf99d7384c30532dcristy int 293599bd523143cfe6d0407e260adf99d7384c30532dcristy level; 293699bd523143cfe6d0407e260adf99d7384c30532dcristy 293799bd523143cfe6d0407e260adf99d7384c30532dcristy register SkipNode 293899bd523143cfe6d0407e260adf99d7384c30532dcristy *root; 293999bd523143cfe6d0407e260adf99d7384c30532dcristy 294099bd523143cfe6d0407e260adf99d7384c30532dcristy register SkipList 294199bd523143cfe6d0407e260adf99d7384c30532dcristy *p; 294299bd523143cfe6d0407e260adf99d7384c30532dcristy 294399bd523143cfe6d0407e260adf99d7384c30532dcristy /* 294499bd523143cfe6d0407e260adf99d7384c30532dcristy Reset the skip-list. 294599bd523143cfe6d0407e260adf99d7384c30532dcristy */ 294699bd523143cfe6d0407e260adf99d7384c30532dcristy p=(&pixel_list->skip_list); 294799bd523143cfe6d0407e260adf99d7384c30532dcristy root=p->nodes+65536UL; 294899bd523143cfe6d0407e260adf99d7384c30532dcristy p->level=0; 294999bd523143cfe6d0407e260adf99d7384c30532dcristy for (level=0; level < 9; level++) 295099bd523143cfe6d0407e260adf99d7384c30532dcristy root->next[level]=65536UL; 295199bd523143cfe6d0407e260adf99d7384c30532dcristy pixel_list->seed=pixel_list->signature++; 295299bd523143cfe6d0407e260adf99d7384c30532dcristy} 295399bd523143cfe6d0407e260adf99d7384c30532dcristy 295499bd523143cfe6d0407e260adf99d7384c30532dcristyMagickExport Image *StatisticImage(const Image *image,const StatisticType type, 295599bd523143cfe6d0407e260adf99d7384c30532dcristy const size_t width,const size_t height,ExceptionInfo *exception) 295699bd523143cfe6d0407e260adf99d7384c30532dcristy{ 295799bd523143cfe6d0407e260adf99d7384c30532dcristy#define StatisticImageTag "Statistic/Image" 295899bd523143cfe6d0407e260adf99d7384c30532dcristy 295999bd523143cfe6d0407e260adf99d7384c30532dcristy CacheView 296099bd523143cfe6d0407e260adf99d7384c30532dcristy *image_view, 296199bd523143cfe6d0407e260adf99d7384c30532dcristy *statistic_view; 296299bd523143cfe6d0407e260adf99d7384c30532dcristy 296399bd523143cfe6d0407e260adf99d7384c30532dcristy Image 296499bd523143cfe6d0407e260adf99d7384c30532dcristy *statistic_image; 296599bd523143cfe6d0407e260adf99d7384c30532dcristy 296699bd523143cfe6d0407e260adf99d7384c30532dcristy MagickBooleanType 296799bd523143cfe6d0407e260adf99d7384c30532dcristy status; 296899bd523143cfe6d0407e260adf99d7384c30532dcristy 296999bd523143cfe6d0407e260adf99d7384c30532dcristy MagickOffsetType 297099bd523143cfe6d0407e260adf99d7384c30532dcristy progress; 297199bd523143cfe6d0407e260adf99d7384c30532dcristy 297299bd523143cfe6d0407e260adf99d7384c30532dcristy PixelList 297305d2ff7ebf21f659f5b11e45afb294e152f4330cdirk **magick_restrict pixel_list; 297499bd523143cfe6d0407e260adf99d7384c30532dcristy 297599bd523143cfe6d0407e260adf99d7384c30532dcristy ssize_t 297699bd523143cfe6d0407e260adf99d7384c30532dcristy center, 297799bd523143cfe6d0407e260adf99d7384c30532dcristy y; 297899bd523143cfe6d0407e260adf99d7384c30532dcristy 297999bd523143cfe6d0407e260adf99d7384c30532dcristy /* 298099bd523143cfe6d0407e260adf99d7384c30532dcristy Initialize statistics image attributes. 298199bd523143cfe6d0407e260adf99d7384c30532dcristy */ 298299bd523143cfe6d0407e260adf99d7384c30532dcristy assert(image != (Image *) NULL); 2983e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy assert(image->signature == MagickCoreSignature); 298499bd523143cfe6d0407e260adf99d7384c30532dcristy if (image->debug != MagickFalse) 298599bd523143cfe6d0407e260adf99d7384c30532dcristy (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); 298699bd523143cfe6d0407e260adf99d7384c30532dcristy assert(exception != (ExceptionInfo *) NULL); 2987e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy assert(exception->signature == MagickCoreSignature); 298899bd523143cfe6d0407e260adf99d7384c30532dcristy statistic_image=CloneImage(image,image->columns,image->rows,MagickTrue, 298999bd523143cfe6d0407e260adf99d7384c30532dcristy exception); 299099bd523143cfe6d0407e260adf99d7384c30532dcristy if (statistic_image == (Image *) NULL) 299199bd523143cfe6d0407e260adf99d7384c30532dcristy return((Image *) NULL); 299299bd523143cfe6d0407e260adf99d7384c30532dcristy status=SetImageStorageClass(statistic_image,DirectClass,exception); 299399bd523143cfe6d0407e260adf99d7384c30532dcristy if (status == MagickFalse) 299499bd523143cfe6d0407e260adf99d7384c30532dcristy { 299599bd523143cfe6d0407e260adf99d7384c30532dcristy statistic_image=DestroyImage(statistic_image); 299699bd523143cfe6d0407e260adf99d7384c30532dcristy return((Image *) NULL); 299799bd523143cfe6d0407e260adf99d7384c30532dcristy } 299899bd523143cfe6d0407e260adf99d7384c30532dcristy pixel_list=AcquirePixelListThreadSet(MagickMax(width,1),MagickMax(height,1)); 299999bd523143cfe6d0407e260adf99d7384c30532dcristy if (pixel_list == (PixelList **) NULL) 300099bd523143cfe6d0407e260adf99d7384c30532dcristy { 300199bd523143cfe6d0407e260adf99d7384c30532dcristy statistic_image=DestroyImage(statistic_image); 300299bd523143cfe6d0407e260adf99d7384c30532dcristy ThrowImageException(ResourceLimitError,"MemoryAllocationFailed"); 300399bd523143cfe6d0407e260adf99d7384c30532dcristy } 300499bd523143cfe6d0407e260adf99d7384c30532dcristy /* 300599bd523143cfe6d0407e260adf99d7384c30532dcristy Make each pixel the min / max / median / mode / etc. of the neighborhood. 300699bd523143cfe6d0407e260adf99d7384c30532dcristy */ 300799bd523143cfe6d0407e260adf99d7384c30532dcristy center=(ssize_t) GetPixelChannels(image)*(image->columns+MagickMax(width,1))* 300899bd523143cfe6d0407e260adf99d7384c30532dcristy (MagickMax(height,1)/2L)+GetPixelChannels(image)*(MagickMax(width,1)/2L); 300999bd523143cfe6d0407e260adf99d7384c30532dcristy status=MagickTrue; 301099bd523143cfe6d0407e260adf99d7384c30532dcristy progress=0; 301146ff2676b1044ea4101ac7a59b83289cd8f6cfdacristy image_view=AcquireVirtualCacheView(image,exception); 301246ff2676b1044ea4101ac7a59b83289cd8f6cfdacristy statistic_view=AcquireAuthenticCacheView(statistic_image,exception); 301399bd523143cfe6d0407e260adf99d7384c30532dcristy#if defined(MAGICKCORE_OPENMP_SUPPORT) 3014ac245f8a51ea65b085d751c41d8ca4b426bdfe5bcristy #pragma omp parallel for schedule(static,4) shared(progress,status) \ 30155e6b259130f9dbe0da4666f734937017babe573acristy magick_threads(image,statistic_image,statistic_image->rows,1) 301699bd523143cfe6d0407e260adf99d7384c30532dcristy#endif 301799bd523143cfe6d0407e260adf99d7384c30532dcristy for (y=0; y < (ssize_t) statistic_image->rows; y++) 301899bd523143cfe6d0407e260adf99d7384c30532dcristy { 301999bd523143cfe6d0407e260adf99d7384c30532dcristy const int 302099bd523143cfe6d0407e260adf99d7384c30532dcristy id = GetOpenMPThreadId(); 302199bd523143cfe6d0407e260adf99d7384c30532dcristy 302299bd523143cfe6d0407e260adf99d7384c30532dcristy register const Quantum 302305d2ff7ebf21f659f5b11e45afb294e152f4330cdirk *magick_restrict p; 302499bd523143cfe6d0407e260adf99d7384c30532dcristy 302599bd523143cfe6d0407e260adf99d7384c30532dcristy register Quantum 302605d2ff7ebf21f659f5b11e45afb294e152f4330cdirk *magick_restrict q; 302799bd523143cfe6d0407e260adf99d7384c30532dcristy 302899bd523143cfe6d0407e260adf99d7384c30532dcristy register ssize_t 302999bd523143cfe6d0407e260adf99d7384c30532dcristy x; 303099bd523143cfe6d0407e260adf99d7384c30532dcristy 303199bd523143cfe6d0407e260adf99d7384c30532dcristy if (status == MagickFalse) 303299bd523143cfe6d0407e260adf99d7384c30532dcristy continue; 303399bd523143cfe6d0407e260adf99d7384c30532dcristy p=GetCacheViewVirtualPixels(image_view,-((ssize_t) MagickMax(width,1)/2L),y- 303499bd523143cfe6d0407e260adf99d7384c30532dcristy (ssize_t) (MagickMax(height,1)/2L),image->columns+MagickMax(width,1), 303599bd523143cfe6d0407e260adf99d7384c30532dcristy MagickMax(height,1),exception); 303699bd523143cfe6d0407e260adf99d7384c30532dcristy q=QueueCacheViewAuthenticPixels(statistic_view,0,y,statistic_image->columns, 1,exception); 303799bd523143cfe6d0407e260adf99d7384c30532dcristy if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL)) 303899bd523143cfe6d0407e260adf99d7384c30532dcristy { 303999bd523143cfe6d0407e260adf99d7384c30532dcristy status=MagickFalse; 304099bd523143cfe6d0407e260adf99d7384c30532dcristy continue; 304199bd523143cfe6d0407e260adf99d7384c30532dcristy } 304299bd523143cfe6d0407e260adf99d7384c30532dcristy for (x=0; x < (ssize_t) statistic_image->columns; x++) 304399bd523143cfe6d0407e260adf99d7384c30532dcristy { 304499bd523143cfe6d0407e260adf99d7384c30532dcristy register ssize_t 304599bd523143cfe6d0407e260adf99d7384c30532dcristy i; 304699bd523143cfe6d0407e260adf99d7384c30532dcristy 304799bd523143cfe6d0407e260adf99d7384c30532dcristy for (i=0; i < (ssize_t) GetPixelChannels(image); i++) 304899bd523143cfe6d0407e260adf99d7384c30532dcristy { 304999bd523143cfe6d0407e260adf99d7384c30532dcristy Quantum 305099bd523143cfe6d0407e260adf99d7384c30532dcristy pixel; 305199bd523143cfe6d0407e260adf99d7384c30532dcristy 305299bd523143cfe6d0407e260adf99d7384c30532dcristy register const Quantum 305305d2ff7ebf21f659f5b11e45afb294e152f4330cdirk *magick_restrict pixels; 305499bd523143cfe6d0407e260adf99d7384c30532dcristy 305599bd523143cfe6d0407e260adf99d7384c30532dcristy register ssize_t 305699bd523143cfe6d0407e260adf99d7384c30532dcristy u; 305799bd523143cfe6d0407e260adf99d7384c30532dcristy 305899bd523143cfe6d0407e260adf99d7384c30532dcristy ssize_t 305999bd523143cfe6d0407e260adf99d7384c30532dcristy v; 306099bd523143cfe6d0407e260adf99d7384c30532dcristy 30615a23c55ddcfdf6ae717dd42d8a1c1a2ff8c6305fcristy PixelChannel channel=GetPixelChannelChannel(image,i); 30625a23c55ddcfdf6ae717dd42d8a1c1a2ff8c6305fcristy PixelTrait traits=GetPixelChannelTraits(image,channel); 30635a23c55ddcfdf6ae717dd42d8a1c1a2ff8c6305fcristy PixelTrait statistic_traits=GetPixelChannelTraits(statistic_image, 30645a23c55ddcfdf6ae717dd42d8a1c1a2ff8c6305fcristy channel); 306599bd523143cfe6d0407e260adf99d7384c30532dcristy if ((traits == UndefinedPixelTrait) || 306699bd523143cfe6d0407e260adf99d7384c30532dcristy (statistic_traits == UndefinedPixelTrait)) 306799bd523143cfe6d0407e260adf99d7384c30532dcristy continue; 30681eced097f7f4f51d5aa14d46079292fa1dcf0e77cristy if (((statistic_traits & CopyPixelTrait) != 0) || 3069883fde11debec15cedb05dc5d7228d8588066bc0cristy (GetPixelReadMask(image,p) == 0)) 307099bd523143cfe6d0407e260adf99d7384c30532dcristy { 307199bd523143cfe6d0407e260adf99d7384c30532dcristy SetPixelChannel(statistic_image,channel,p[center+i],q); 307299bd523143cfe6d0407e260adf99d7384c30532dcristy continue; 307399bd523143cfe6d0407e260adf99d7384c30532dcristy } 307499bd523143cfe6d0407e260adf99d7384c30532dcristy pixels=p; 307599bd523143cfe6d0407e260adf99d7384c30532dcristy ResetPixelList(pixel_list[id]); 307699bd523143cfe6d0407e260adf99d7384c30532dcristy for (v=0; v < (ssize_t) MagickMax(height,1); v++) 307799bd523143cfe6d0407e260adf99d7384c30532dcristy { 307899bd523143cfe6d0407e260adf99d7384c30532dcristy for (u=0; u < (ssize_t) MagickMax(width,1); u++) 307999bd523143cfe6d0407e260adf99d7384c30532dcristy { 3080b0de93fdedaac769cb08e15b3ec176d4c9078907cristy InsertPixelList(pixels[i],pixel_list[id]); 308199bd523143cfe6d0407e260adf99d7384c30532dcristy pixels+=GetPixelChannels(image); 308299bd523143cfe6d0407e260adf99d7384c30532dcristy } 30830c7bac1cfcf74e19cc41d9069a904b0a6fc9c291cristy pixels+=GetPixelChannels(image)*image->columns; 308499bd523143cfe6d0407e260adf99d7384c30532dcristy } 308599bd523143cfe6d0407e260adf99d7384c30532dcristy switch (type) 308699bd523143cfe6d0407e260adf99d7384c30532dcristy { 308799bd523143cfe6d0407e260adf99d7384c30532dcristy case GradientStatistic: 308899bd523143cfe6d0407e260adf99d7384c30532dcristy { 3089a19f1d70e9a9f88279c4ecafe6dfafc1f9a09599cristy double 309099bd523143cfe6d0407e260adf99d7384c30532dcristy maximum, 309199bd523143cfe6d0407e260adf99d7384c30532dcristy minimum; 309299bd523143cfe6d0407e260adf99d7384c30532dcristy 309399bd523143cfe6d0407e260adf99d7384c30532dcristy GetMinimumPixelList(pixel_list[id],&pixel); 3094a19f1d70e9a9f88279c4ecafe6dfafc1f9a09599cristy minimum=(double) pixel; 309599bd523143cfe6d0407e260adf99d7384c30532dcristy GetMaximumPixelList(pixel_list[id],&pixel); 3096a19f1d70e9a9f88279c4ecafe6dfafc1f9a09599cristy maximum=(double) pixel; 309799bd523143cfe6d0407e260adf99d7384c30532dcristy pixel=ClampToQuantum(MagickAbsoluteValue(maximum-minimum)); 309899bd523143cfe6d0407e260adf99d7384c30532dcristy break; 309999bd523143cfe6d0407e260adf99d7384c30532dcristy } 310099bd523143cfe6d0407e260adf99d7384c30532dcristy case MaximumStatistic: 310199bd523143cfe6d0407e260adf99d7384c30532dcristy { 310299bd523143cfe6d0407e260adf99d7384c30532dcristy GetMaximumPixelList(pixel_list[id],&pixel); 310399bd523143cfe6d0407e260adf99d7384c30532dcristy break; 310499bd523143cfe6d0407e260adf99d7384c30532dcristy } 310599bd523143cfe6d0407e260adf99d7384c30532dcristy case MeanStatistic: 310699bd523143cfe6d0407e260adf99d7384c30532dcristy { 310799bd523143cfe6d0407e260adf99d7384c30532dcristy GetMeanPixelList(pixel_list[id],&pixel); 310899bd523143cfe6d0407e260adf99d7384c30532dcristy break; 310999bd523143cfe6d0407e260adf99d7384c30532dcristy } 311099bd523143cfe6d0407e260adf99d7384c30532dcristy case MedianStatistic: 311199bd523143cfe6d0407e260adf99d7384c30532dcristy default: 311299bd523143cfe6d0407e260adf99d7384c30532dcristy { 311399bd523143cfe6d0407e260adf99d7384c30532dcristy GetMedianPixelList(pixel_list[id],&pixel); 311499bd523143cfe6d0407e260adf99d7384c30532dcristy break; 311599bd523143cfe6d0407e260adf99d7384c30532dcristy } 311699bd523143cfe6d0407e260adf99d7384c30532dcristy case MinimumStatistic: 311799bd523143cfe6d0407e260adf99d7384c30532dcristy { 311899bd523143cfe6d0407e260adf99d7384c30532dcristy GetMinimumPixelList(pixel_list[id],&pixel); 311999bd523143cfe6d0407e260adf99d7384c30532dcristy break; 312099bd523143cfe6d0407e260adf99d7384c30532dcristy } 312199bd523143cfe6d0407e260adf99d7384c30532dcristy case ModeStatistic: 312299bd523143cfe6d0407e260adf99d7384c30532dcristy { 312399bd523143cfe6d0407e260adf99d7384c30532dcristy GetModePixelList(pixel_list[id],&pixel); 312499bd523143cfe6d0407e260adf99d7384c30532dcristy break; 312599bd523143cfe6d0407e260adf99d7384c30532dcristy } 312699bd523143cfe6d0407e260adf99d7384c30532dcristy case NonpeakStatistic: 312799bd523143cfe6d0407e260adf99d7384c30532dcristy { 312899bd523143cfe6d0407e260adf99d7384c30532dcristy GetNonpeakPixelList(pixel_list[id],&pixel); 312999bd523143cfe6d0407e260adf99d7384c30532dcristy break; 313099bd523143cfe6d0407e260adf99d7384c30532dcristy } 3131180908c3457893af93b890e3d01a992727574877cristy case RootMeanSquareStatistic: 3132180908c3457893af93b890e3d01a992727574877cristy { 3133180908c3457893af93b890e3d01a992727574877cristy GetRootMeanSquarePixelList(pixel_list[id],&pixel); 3134180908c3457893af93b890e3d01a992727574877cristy break; 3135180908c3457893af93b890e3d01a992727574877cristy } 313699bd523143cfe6d0407e260adf99d7384c30532dcristy case StandardDeviationStatistic: 313799bd523143cfe6d0407e260adf99d7384c30532dcristy { 313899bd523143cfe6d0407e260adf99d7384c30532dcristy GetStandardDeviationPixelList(pixel_list[id],&pixel); 313999bd523143cfe6d0407e260adf99d7384c30532dcristy break; 314099bd523143cfe6d0407e260adf99d7384c30532dcristy } 314199bd523143cfe6d0407e260adf99d7384c30532dcristy } 314299bd523143cfe6d0407e260adf99d7384c30532dcristy SetPixelChannel(statistic_image,channel,pixel,q); 314399bd523143cfe6d0407e260adf99d7384c30532dcristy } 314499bd523143cfe6d0407e260adf99d7384c30532dcristy p+=GetPixelChannels(image); 314599bd523143cfe6d0407e260adf99d7384c30532dcristy q+=GetPixelChannels(statistic_image); 314699bd523143cfe6d0407e260adf99d7384c30532dcristy } 314799bd523143cfe6d0407e260adf99d7384c30532dcristy if (SyncCacheViewAuthenticPixels(statistic_view,exception) == MagickFalse) 314899bd523143cfe6d0407e260adf99d7384c30532dcristy status=MagickFalse; 314999bd523143cfe6d0407e260adf99d7384c30532dcristy if (image->progress_monitor != (MagickProgressMonitor) NULL) 315099bd523143cfe6d0407e260adf99d7384c30532dcristy { 315199bd523143cfe6d0407e260adf99d7384c30532dcristy MagickBooleanType 315299bd523143cfe6d0407e260adf99d7384c30532dcristy proceed; 315399bd523143cfe6d0407e260adf99d7384c30532dcristy 315499bd523143cfe6d0407e260adf99d7384c30532dcristy#if defined(MAGICKCORE_OPENMP_SUPPORT) 3155ac245f8a51ea65b085d751c41d8ca4b426bdfe5bcristy #pragma omp critical (MagickCore_StatisticImage) 315699bd523143cfe6d0407e260adf99d7384c30532dcristy#endif 315799bd523143cfe6d0407e260adf99d7384c30532dcristy proceed=SetImageProgress(image,StatisticImageTag,progress++, 315899bd523143cfe6d0407e260adf99d7384c30532dcristy image->rows); 315999bd523143cfe6d0407e260adf99d7384c30532dcristy if (proceed == MagickFalse) 316099bd523143cfe6d0407e260adf99d7384c30532dcristy status=MagickFalse; 316199bd523143cfe6d0407e260adf99d7384c30532dcristy } 316299bd523143cfe6d0407e260adf99d7384c30532dcristy } 316399bd523143cfe6d0407e260adf99d7384c30532dcristy statistic_view=DestroyCacheView(statistic_view); 316499bd523143cfe6d0407e260adf99d7384c30532dcristy image_view=DestroyCacheView(image_view); 316599bd523143cfe6d0407e260adf99d7384c30532dcristy pixel_list=DestroyPixelListThreadSet(pixel_list); 31661c2f48d0fbbad5757296fca9324fa14033f56632cristy if (status == MagickFalse) 31671c2f48d0fbbad5757296fca9324fa14033f56632cristy statistic_image=DestroyImage(statistic_image); 316899bd523143cfe6d0407e260adf99d7384c30532dcristy return(statistic_image); 316999bd523143cfe6d0407e260adf99d7384c30532dcristy} 3170