17b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk// This may look like C code, but it is really -*- C++ -*- 27b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk// 377328896b876314656427663695bc7b2c9be3f74dirk// Copyright Dirk Lemstra 2014-2015 47b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk// 57b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk// Implementation of channel moments. 67b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk// 77b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk 87b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk#define MAGICKCORE_IMPLEMENTATION 1 97b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk#define MAGICK_PLUSPLUS_IMPLEMENTATION 1 107b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk 117b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk#include "Magick++/Include.h" 127b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk#include "Magick++/Exception.h" 137b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk#include "Magick++/Statistic.h" 1477328896b876314656427663695bc7b2c9be3f74dirk#include "Magick++/Image.h" 157b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk 167b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirkusing namespace std; 177b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk 187b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirkMagick::ChannelMoments::ChannelMoments(void) 19130da8409cb096ee6288a3ae7684ee5c7a328b0cdirk : _channel(SyncPixelChannel), 20130da8409cb096ee6288a3ae7684ee5c7a328b0cdirk _huInvariants(8), 217b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk _centroidX(0.0), 227b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk _centroidY(0.0), 237b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk _ellipseAxisX(0.0), 247b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk _ellipseAxisY(0.0), 257b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk _ellipseAngle(0.0), 267b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk _ellipseEccentricity(0.0), 277b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk _ellipseIntensity(0.0) 287b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk{ 297b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk} 307b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk 317b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirkMagick::ChannelMoments::ChannelMoments(const ChannelMoments &channelMoments_) 32130da8409cb096ee6288a3ae7684ee5c7a328b0cdirk : _channel(channelMoments_._channel), 33130da8409cb096ee6288a3ae7684ee5c7a328b0cdirk _huInvariants(channelMoments_._huInvariants), 347b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk _centroidX(channelMoments_._centroidX), 357b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk _centroidY(channelMoments_._centroidY), 367b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk _ellipseAxisX(channelMoments_._ellipseAxisX), 377b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk _ellipseAxisY(channelMoments_._ellipseAxisY), 387b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk _ellipseAngle(channelMoments_._ellipseAngle), 397b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk _ellipseEccentricity(channelMoments_._ellipseEccentricity), 407b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk _ellipseIntensity(channelMoments_._ellipseIntensity) 417b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk{ 427b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk} 437b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk 447b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirkMagick::ChannelMoments::~ChannelMoments(void) 457b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk{ 467b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk} 477b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk 487b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirkdouble Magick::ChannelMoments::centroidX(void) const 497b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk{ 507b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk return(_centroidX); 517b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk} 527b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk 537b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirkdouble Magick::ChannelMoments::centroidY(void) const 547b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk{ 557b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk return(_centroidY); 567b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk} 577b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk 587b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirkMagick::PixelChannel Magick::ChannelMoments::channel(void) const 597b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk{ 607b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk return(_channel); 617b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk} 627b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk 637b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirkdouble Magick::ChannelMoments::ellipseAxisX(void) const 647b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk{ 657b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk return(_ellipseAxisX); 667b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk} 677b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk 687b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirkdouble Magick::ChannelMoments::ellipseAxisY(void) const 697b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk{ 707b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk return(_ellipseAxisY); 717b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk} 727b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk 737b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirkdouble Magick::ChannelMoments::ellipseAngle(void) const 747b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk{ 757b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk return(_ellipseAngle); 767b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk} 777b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk 787b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirkdouble Magick::ChannelMoments::ellipseEccentricity(void) const 797b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk{ 807b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk return(_ellipseEccentricity); 817b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk} 827b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk 837b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirkdouble Magick::ChannelMoments::ellipseIntensity(void) const 847b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk{ 857b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk return(_ellipseIntensity); 867b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk} 877b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk 887b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirkdouble Magick::ChannelMoments::huInvariants(const size_t index_) const 897b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk{ 907b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk if (index_ > 7) 917b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk throw ErrorOption("Valid range for index is 0-7"); 927b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk 937b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk return(_huInvariants.at(index_)); 947b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk} 957b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk 967b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirkbool Magick::ChannelMoments::isValid() const 977b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk{ 987b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk return(_channel != SyncPixelChannel); 997b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk} 1007b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk 1017b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirkMagick::ChannelMoments::ChannelMoments(const PixelChannel channel_, 1027b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk const MagickCore::ChannelMoments *channelMoments_) 103130da8409cb096ee6288a3ae7684ee5c7a328b0cdirk : _channel(channel_), 104130da8409cb096ee6288a3ae7684ee5c7a328b0cdirk _huInvariants(), 1057b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk _centroidX(channelMoments_->centroid.x), 1067b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk _centroidY(channelMoments_->centroid.y), 1077b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk _ellipseAxisX(channelMoments_->ellipse_axis.x), 1087b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk _ellipseAxisY(channelMoments_->ellipse_axis.y), 1097b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk _ellipseAngle(channelMoments_->ellipse_angle), 1107b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk _ellipseEccentricity(channelMoments_->ellipse_eccentricity), 1117b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk _ellipseIntensity(channelMoments_->ellipse_intensity) 1127b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk{ 113e316d154e7b050fab78dbf86b33f0797594939cadirk register ssize_t 1147b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk i; 1157b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk 1167b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk for (i=0; i<8; i++) 11757f71289ef12fb275c908972156e7e397d9e07bbcristy _huInvariants.push_back(channelMoments_->invariant[i]); 1187b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk} 1197b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk 120e316d154e7b050fab78dbf86b33f0797594939cadirkMagick::ChannelPerceptualHash::ChannelPerceptualHash(void) 121e316d154e7b050fab78dbf86b33f0797594939cadirk : _channel(SyncPixelChannel), 122e316d154e7b050fab78dbf86b33f0797594939cadirk _srgbHuPhash(7), 123e316d154e7b050fab78dbf86b33f0797594939cadirk _hclpHuPhash(7) 124e316d154e7b050fab78dbf86b33f0797594939cadirk{ 125e316d154e7b050fab78dbf86b33f0797594939cadirk} 126e316d154e7b050fab78dbf86b33f0797594939cadirk 127e316d154e7b050fab78dbf86b33f0797594939cadirkMagick::ChannelPerceptualHash::ChannelPerceptualHash( 128e316d154e7b050fab78dbf86b33f0797594939cadirk const ChannelPerceptualHash &channelPerceptualHash_) 129e316d154e7b050fab78dbf86b33f0797594939cadirk : _channel(channelPerceptualHash_._channel), 130e316d154e7b050fab78dbf86b33f0797594939cadirk _srgbHuPhash(channelPerceptualHash_._srgbHuPhash), 131e316d154e7b050fab78dbf86b33f0797594939cadirk _hclpHuPhash(channelPerceptualHash_._hclpHuPhash) 132e316d154e7b050fab78dbf86b33f0797594939cadirk{ 133e316d154e7b050fab78dbf86b33f0797594939cadirk} 134e316d154e7b050fab78dbf86b33f0797594939cadirk 135e316d154e7b050fab78dbf86b33f0797594939cadirkMagick::ChannelPerceptualHash::ChannelPerceptualHash( 136e316d154e7b050fab78dbf86b33f0797594939cadirk const PixelChannel channel_,const std::string &hash_) 137e316d154e7b050fab78dbf86b33f0797594939cadirk : _channel(channel_), 138e316d154e7b050fab78dbf86b33f0797594939cadirk _srgbHuPhash(7), 139e316d154e7b050fab78dbf86b33f0797594939cadirk _hclpHuPhash(7) 140e316d154e7b050fab78dbf86b33f0797594939cadirk{ 141e316d154e7b050fab78dbf86b33f0797594939cadirk register ssize_t 142e316d154e7b050fab78dbf86b33f0797594939cadirk i; 143e316d154e7b050fab78dbf86b33f0797594939cadirk 144e316d154e7b050fab78dbf86b33f0797594939cadirk if (hash_.length() != 70) 145e316d154e7b050fab78dbf86b33f0797594939cadirk throw ErrorOption("Invalid hash length"); 146e316d154e7b050fab78dbf86b33f0797594939cadirk 147e316d154e7b050fab78dbf86b33f0797594939cadirk for (i=0; i<14; i++) 148e316d154e7b050fab78dbf86b33f0797594939cadirk { 149b27956a2e5105465a555508ddb3aa87881bcf55edirk unsigned int 150e316d154e7b050fab78dbf86b33f0797594939cadirk hex; 151e316d154e7b050fab78dbf86b33f0797594939cadirk 152e316d154e7b050fab78dbf86b33f0797594939cadirk double 153e316d154e7b050fab78dbf86b33f0797594939cadirk value; 154e316d154e7b050fab78dbf86b33f0797594939cadirk 155e316d154e7b050fab78dbf86b33f0797594939cadirk if (sscanf(hash_.substr(i*5,5).c_str(),"%05x",&hex) != 1) 156e316d154e7b050fab78dbf86b33f0797594939cadirk throw ErrorOption("Invalid hash value"); 157e316d154e7b050fab78dbf86b33f0797594939cadirk 1584620adfacf4d6efe93b83ea4b0c3f68bb47736e6dirk value=((unsigned short)hex) / pow(10.0, (double)(hex >> 17)); 159e316d154e7b050fab78dbf86b33f0797594939cadirk if (hex & (1 << 16)) 160e316d154e7b050fab78dbf86b33f0797594939cadirk value=-value; 161e316d154e7b050fab78dbf86b33f0797594939cadirk if (i < 7) 162e316d154e7b050fab78dbf86b33f0797594939cadirk _srgbHuPhash[i]=value; 163e316d154e7b050fab78dbf86b33f0797594939cadirk else 164e316d154e7b050fab78dbf86b33f0797594939cadirk _hclpHuPhash[i-7]=value; 165e316d154e7b050fab78dbf86b33f0797594939cadirk } 166e316d154e7b050fab78dbf86b33f0797594939cadirk} 167e316d154e7b050fab78dbf86b33f0797594939cadirk 168e316d154e7b050fab78dbf86b33f0797594939cadirkMagick::ChannelPerceptualHash::~ChannelPerceptualHash(void) 169e316d154e7b050fab78dbf86b33f0797594939cadirk{ 170e316d154e7b050fab78dbf86b33f0797594939cadirk} 171e316d154e7b050fab78dbf86b33f0797594939cadirk 172e316d154e7b050fab78dbf86b33f0797594939cadirkMagick::ChannelPerceptualHash::operator std::string() const 173e316d154e7b050fab78dbf86b33f0797594939cadirk{ 174e316d154e7b050fab78dbf86b33f0797594939cadirk std::string 175e316d154e7b050fab78dbf86b33f0797594939cadirk hash; 176e316d154e7b050fab78dbf86b33f0797594939cadirk 177e316d154e7b050fab78dbf86b33f0797594939cadirk register ssize_t 178e316d154e7b050fab78dbf86b33f0797594939cadirk i; 179e316d154e7b050fab78dbf86b33f0797594939cadirk 180e316d154e7b050fab78dbf86b33f0797594939cadirk if (!isValid()) 181e316d154e7b050fab78dbf86b33f0797594939cadirk return(std::string()); 182e316d154e7b050fab78dbf86b33f0797594939cadirk 183e316d154e7b050fab78dbf86b33f0797594939cadirk for (i=0; i<14; i++) 184e316d154e7b050fab78dbf86b33f0797594939cadirk { 185e316d154e7b050fab78dbf86b33f0797594939cadirk char 186e316d154e7b050fab78dbf86b33f0797594939cadirk buffer[6]; 187e316d154e7b050fab78dbf86b33f0797594939cadirk 188e316d154e7b050fab78dbf86b33f0797594939cadirk double 189e316d154e7b050fab78dbf86b33f0797594939cadirk value; 190e316d154e7b050fab78dbf86b33f0797594939cadirk 191b27956a2e5105465a555508ddb3aa87881bcf55edirk unsigned int 192e316d154e7b050fab78dbf86b33f0797594939cadirk hex; 193e316d154e7b050fab78dbf86b33f0797594939cadirk 194e316d154e7b050fab78dbf86b33f0797594939cadirk if (i < 7) 195e316d154e7b050fab78dbf86b33f0797594939cadirk value=_srgbHuPhash[i]; 196e316d154e7b050fab78dbf86b33f0797594939cadirk else 197e316d154e7b050fab78dbf86b33f0797594939cadirk value=_hclpHuPhash[i-7]; 198e316d154e7b050fab78dbf86b33f0797594939cadirk 199e316d154e7b050fab78dbf86b33f0797594939cadirk hex=0; 200e316d154e7b050fab78dbf86b33f0797594939cadirk while(hex < 7 && fabs(value*10) < 65536) 201e316d154e7b050fab78dbf86b33f0797594939cadirk { 202e316d154e7b050fab78dbf86b33f0797594939cadirk value=value*10; 203e316d154e7b050fab78dbf86b33f0797594939cadirk hex++; 204e316d154e7b050fab78dbf86b33f0797594939cadirk } 205e316d154e7b050fab78dbf86b33f0797594939cadirk 206e316d154e7b050fab78dbf86b33f0797594939cadirk hex=(hex<<1); 207e316d154e7b050fab78dbf86b33f0797594939cadirk if (value < 0.0) 208e316d154e7b050fab78dbf86b33f0797594939cadirk hex|=1; 209b27956a2e5105465a555508ddb3aa87881bcf55edirk hex=(hex<<16)+(unsigned int)(value < 0.0 ? -(value - 0.5) : value + 0.5); 210e316d154e7b050fab78dbf86b33f0797594939cadirk (void) FormatLocaleString(buffer,6,"%05x",hex); 211e316d154e7b050fab78dbf86b33f0797594939cadirk hash+=std::string(buffer); 212e316d154e7b050fab78dbf86b33f0797594939cadirk } 213e316d154e7b050fab78dbf86b33f0797594939cadirk return(hash); 214e316d154e7b050fab78dbf86b33f0797594939cadirk} 215e316d154e7b050fab78dbf86b33f0797594939cadirk 216e316d154e7b050fab78dbf86b33f0797594939cadirkMagick::PixelChannel Magick::ChannelPerceptualHash::channel() const 217e316d154e7b050fab78dbf86b33f0797594939cadirk{ 218e316d154e7b050fab78dbf86b33f0797594939cadirk return(_channel); 219e316d154e7b050fab78dbf86b33f0797594939cadirk} 220e316d154e7b050fab78dbf86b33f0797594939cadirk 221e316d154e7b050fab78dbf86b33f0797594939cadirkbool Magick::ChannelPerceptualHash::isValid() const 222e316d154e7b050fab78dbf86b33f0797594939cadirk{ 223e316d154e7b050fab78dbf86b33f0797594939cadirk return(_channel != SyncPixelChannel); 224e316d154e7b050fab78dbf86b33f0797594939cadirk} 225e316d154e7b050fab78dbf86b33f0797594939cadirk 226e316d154e7b050fab78dbf86b33f0797594939cadirkdouble Magick::ChannelPerceptualHash::sumSquaredDifferences( 227e316d154e7b050fab78dbf86b33f0797594939cadirk const ChannelPerceptualHash &channelPerceptualHash_) 228e316d154e7b050fab78dbf86b33f0797594939cadirk{ 229e316d154e7b050fab78dbf86b33f0797594939cadirk double 230e316d154e7b050fab78dbf86b33f0797594939cadirk ssd; 231e316d154e7b050fab78dbf86b33f0797594939cadirk 232e316d154e7b050fab78dbf86b33f0797594939cadirk register ssize_t 233e316d154e7b050fab78dbf86b33f0797594939cadirk i; 234e316d154e7b050fab78dbf86b33f0797594939cadirk 235e316d154e7b050fab78dbf86b33f0797594939cadirk ssd=0.0; 236e316d154e7b050fab78dbf86b33f0797594939cadirk for (i=0; i<7; i++) 237e316d154e7b050fab78dbf86b33f0797594939cadirk { 238e316d154e7b050fab78dbf86b33f0797594939cadirk ssd+=((_srgbHuPhash[i]-channelPerceptualHash_._srgbHuPhash[i])* 239e316d154e7b050fab78dbf86b33f0797594939cadirk (_srgbHuPhash[i]-channelPerceptualHash_._srgbHuPhash[i])); 240e316d154e7b050fab78dbf86b33f0797594939cadirk ssd+=((_hclpHuPhash[i]-channelPerceptualHash_._hclpHuPhash[i])* 241e316d154e7b050fab78dbf86b33f0797594939cadirk (_hclpHuPhash[i]-channelPerceptualHash_._hclpHuPhash[i])); 242e316d154e7b050fab78dbf86b33f0797594939cadirk } 243e316d154e7b050fab78dbf86b33f0797594939cadirk return(ssd); 244e316d154e7b050fab78dbf86b33f0797594939cadirk} 245e316d154e7b050fab78dbf86b33f0797594939cadirk 246e316d154e7b050fab78dbf86b33f0797594939cadirkdouble Magick::ChannelPerceptualHash::srgbHuPhash(const size_t index_) const 247e316d154e7b050fab78dbf86b33f0797594939cadirk{ 248e316d154e7b050fab78dbf86b33f0797594939cadirk if (index_ > 6) 249e316d154e7b050fab78dbf86b33f0797594939cadirk throw ErrorOption("Valid range for index is 0-6"); 250e316d154e7b050fab78dbf86b33f0797594939cadirk 251e316d154e7b050fab78dbf86b33f0797594939cadirk return(_srgbHuPhash.at(index_)); 252e316d154e7b050fab78dbf86b33f0797594939cadirk} 253e316d154e7b050fab78dbf86b33f0797594939cadirk 254e316d154e7b050fab78dbf86b33f0797594939cadirkdouble Magick::ChannelPerceptualHash::hclpHuPhash(const size_t index_) const 255e316d154e7b050fab78dbf86b33f0797594939cadirk{ 256e316d154e7b050fab78dbf86b33f0797594939cadirk if (index_ > 6) 257e316d154e7b050fab78dbf86b33f0797594939cadirk throw ErrorOption("Valid range for index is 0-6"); 258e316d154e7b050fab78dbf86b33f0797594939cadirk 259e316d154e7b050fab78dbf86b33f0797594939cadirk return(_hclpHuPhash.at(index_)); 260e316d154e7b050fab78dbf86b33f0797594939cadirk} 261e316d154e7b050fab78dbf86b33f0797594939cadirk 262e316d154e7b050fab78dbf86b33f0797594939cadirkMagick::ChannelPerceptualHash::ChannelPerceptualHash( 263e316d154e7b050fab78dbf86b33f0797594939cadirk const PixelChannel channel_, 264e316d154e7b050fab78dbf86b33f0797594939cadirk const MagickCore::ChannelPerceptualHash *channelPerceptualHash_) 265e316d154e7b050fab78dbf86b33f0797594939cadirk : _channel(channel_), 266e316d154e7b050fab78dbf86b33f0797594939cadirk _srgbHuPhash(7), 267e316d154e7b050fab78dbf86b33f0797594939cadirk _hclpHuPhash(7) 268e316d154e7b050fab78dbf86b33f0797594939cadirk{ 269e316d154e7b050fab78dbf86b33f0797594939cadirk register ssize_t 270e316d154e7b050fab78dbf86b33f0797594939cadirk i; 271e316d154e7b050fab78dbf86b33f0797594939cadirk 272e316d154e7b050fab78dbf86b33f0797594939cadirk for (i=0; i<7; i++) 273e316d154e7b050fab78dbf86b33f0797594939cadirk { 274e316d154e7b050fab78dbf86b33f0797594939cadirk _srgbHuPhash[i]=channelPerceptualHash_->srgb_hu_phash[i]; 275e316d154e7b050fab78dbf86b33f0797594939cadirk _hclpHuPhash[i]=channelPerceptualHash_->hclp_hu_phash[i]; 276e316d154e7b050fab78dbf86b33f0797594939cadirk } 277e316d154e7b050fab78dbf86b33f0797594939cadirk} 278e316d154e7b050fab78dbf86b33f0797594939cadirk 2797b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirkMagick::ChannelStatistics::ChannelStatistics(void) 2807b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk : _channel(SyncPixelChannel), 2817b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk _area(0.0), 2827b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk _depth(0.0), 2836d0da8396cc07f9eee0b367dba6fd522d6a6be3fdirk _entropy(0.0), 2847b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk _kurtosis(0.0), 2857b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk _maxima(0.0), 2867b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk _mean(0.0), 2877b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk _minima(0.0), 2887b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk _skewness(0.0), 2897b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk _standardDeviation(0.0), 2907b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk _sum(0.0), 2917b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk _sumCubed(0.0), 2927b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk _sumFourthPower(0.0), 2937b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk _sumSquared(0.0), 2947b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk _variance(0.0) 2957b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk{ 2967b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk} 2977b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk 2987b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirkMagick::ChannelStatistics::ChannelStatistics( 2997b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk const ChannelStatistics &channelStatistics_) 3007b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk : _channel(channelStatistics_._channel), 3017b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk _area(channelStatistics_._area), 3027b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk _depth(channelStatistics_._depth), 3036d0da8396cc07f9eee0b367dba6fd522d6a6be3fdirk _entropy(channelStatistics_._entropy), 3047b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk _kurtosis(channelStatistics_._kurtosis), 3057b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk _maxima(channelStatistics_._maxima), 3067b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk _mean(channelStatistics_._mean), 3077b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk _minima(channelStatistics_._minima), 3087b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk _skewness(channelStatistics_._skewness), 3097b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk _standardDeviation(channelStatistics_._standardDeviation), 3107b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk _sum(channelStatistics_._sum), 3117b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk _sumCubed(channelStatistics_._sumCubed), 3127b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk _sumFourthPower(channelStatistics_._sumFourthPower), 3137b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk _sumSquared(channelStatistics_._sumSquared), 3147b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk _variance(channelStatistics_._variance) 3157b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk{ 3167b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk} 3177b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk 3187b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirkMagick::ChannelStatistics::~ChannelStatistics(void) 3197b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk{ 3207b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk} 3217b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk 3227b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirkdouble Magick::ChannelStatistics::area() const 3237b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk{ 3247b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk return(_area); 3257b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk} 3267b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk 3277b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirkMagick::PixelChannel Magick::ChannelStatistics::channel() const 3287b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk{ 3297b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk return(_channel); 3307b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk} 3317b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk 3327b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirksize_t Magick::ChannelStatistics::depth() const 3337b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk{ 3347b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk return(_depth); 3357b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk} 3367b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk 3376d0da8396cc07f9eee0b367dba6fd522d6a6be3fdirkdouble Magick::ChannelStatistics::entropy() const 3386d0da8396cc07f9eee0b367dba6fd522d6a6be3fdirk{ 3396d0da8396cc07f9eee0b367dba6fd522d6a6be3fdirk return(_entropy); 3406d0da8396cc07f9eee0b367dba6fd522d6a6be3fdirk} 3416d0da8396cc07f9eee0b367dba6fd522d6a6be3fdirk 3427b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirkbool Magick::ChannelStatistics::isValid() const 3437b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk{ 3447b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk return(_channel != SyncPixelChannel); 3457b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk} 3467b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk 3477b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirkdouble Magick::ChannelStatistics::kurtosis() const 3487b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk{ 3497b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk return(_kurtosis); 3507b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk} 3517b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk 3527b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirkdouble Magick::ChannelStatistics::maxima() const 3537b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk{ 3547b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk return(_maxima); 3557b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk} 3567b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk 3577b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirkdouble Magick::ChannelStatistics::mean() const 3587b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk{ 3597b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk return(_mean); 3607b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk} 3617b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk 3627b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirkdouble Magick::ChannelStatistics::minima() const 3637b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk{ 3647b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk return(_minima); 3657b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk} 3667b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk 3677b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirkdouble Magick::ChannelStatistics::skewness() const 3687b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk{ 3697b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk return(_skewness); 3707b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk} 3717b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk 3727b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirkdouble Magick::ChannelStatistics::standardDeviation() const 3737b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk{ 3747b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk return(_standardDeviation); 3757b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk} 3767b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk 3777b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirkdouble Magick::ChannelStatistics::sum() const 3787b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk{ 3797b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk return(_sum); 3807b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk} 3817b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk 3827b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirkdouble Magick::ChannelStatistics::sumCubed() const 3837b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk{ 3847b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk return(_sumCubed); 3857b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk} 3867b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk 3877b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirkdouble Magick::ChannelStatistics::sumFourthPower() const 3887b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk{ 3897b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk return(_sumFourthPower); 3907b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk} 3917b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk 3927b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirkdouble Magick::ChannelStatistics::sumSquared() const 3937b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk{ 3947b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk return(_sumSquared); 3957b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk} 3967b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk 3977b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirkdouble Magick::ChannelStatistics::variance() const 3987b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk{ 3997b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk return(_variance); 4007b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk} 4017b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk 4027b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirkMagick::ChannelStatistics::ChannelStatistics(const PixelChannel channel_, 4037b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk const MagickCore::ChannelStatistics *channelStatistics_) 4047b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk : _channel(channel_), 4057b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk _area(channelStatistics_->area), 4067b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk _depth(channelStatistics_->depth), 4076d0da8396cc07f9eee0b367dba6fd522d6a6be3fdirk _entropy(channelStatistics_->entropy), 4087b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk _kurtosis(channelStatistics_->kurtosis), 4097b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk _maxima(channelStatistics_->maxima), 4107b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk _mean(channelStatistics_->mean), 4117b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk _minima(channelStatistics_->minima), 4127b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk _skewness(channelStatistics_->skewness), 4137b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk _standardDeviation(channelStatistics_->standard_deviation), 4147b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk _sum(channelStatistics_->sum), 4157b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk _sumCubed(channelStatistics_->sum_cubed), 4167b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk _sumFourthPower(channelStatistics_->sum_fourth_power), 4177b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk _sumSquared(channelStatistics_->sum_squared), 4187b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk _variance(channelStatistics_->variance) 4197b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk{ 4207b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk} 4217b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk 4227b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirkMagick::ImageMoments::ImageMoments(void) 4237b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk : _channels() 4247b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk{ 4257b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk} 4267b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk 4277b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirkMagick::ImageMoments::ImageMoments(const ImageMoments &imageMoments_) 4287b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk : _channels(imageMoments_._channels) 4297b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk{ 4307b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk} 4317b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk 4327b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirkMagick::ImageMoments::~ImageMoments(void) 4337b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk{ 4347b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk} 4357b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk 4367b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirkMagick::ChannelMoments Magick::ImageMoments::channel( 4377b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk const PixelChannel channel_) const 4387b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk{ 4397b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk for (std::vector<ChannelMoments>::const_iterator it = _channels.begin(); 4407b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk it != _channels.end(); ++it) 4417b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk { 4427b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk if (it->channel() == channel_) 4437b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk return(*it); 4447b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk } 4457b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk return(ChannelMoments()); 4467b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk} 4477b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk 44877328896b876314656427663695bc7b2c9be3f74dirkMagick::ImageMoments::ImageMoments(const Image &image_) 4497b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk : _channels() 4507b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk{ 4517b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk MagickCore::ChannelMoments* 4527b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk channel_moments; 4537b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk 4547b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk GetPPException; 45577328896b876314656427663695bc7b2c9be3f74dirk channel_moments=GetImageMoments(image_.constImage(),exceptionInfo); 4567b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk if (channel_moments != (MagickCore::ChannelMoments *) NULL) 4577b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk { 4587b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk register ssize_t 4597b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk i; 4607b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk 46177328896b876314656427663695bc7b2c9be3f74dirk for (i=0; i < (ssize_t) GetPixelChannels(image_.constImage()); i++) 4627b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk { 46377328896b876314656427663695bc7b2c9be3f74dirk PixelChannel channel=GetPixelChannelChannel(image_.constImage(),i); 46477328896b876314656427663695bc7b2c9be3f74dirk PixelTrait traits=GetPixelChannelTraits(image_.constImage(),channel); 4657b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk if (traits == UndefinedPixelTrait) 4667b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk continue; 4677b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk if ((traits & UpdatePixelTrait) == 0) 4687b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk continue; 4697b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk _channels.push_back(Magick::ChannelMoments(channel, 4707b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk &channel_moments[channel])); 4717b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk } 4727b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk _channels.push_back(Magick::ChannelMoments(CompositePixelChannel, 4737b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk &channel_moments[CompositePixelChannel])); 4747b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk channel_moments=(MagickCore::ChannelMoments *) RelinquishMagickMemory( 4757b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk channel_moments); 4767b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk } 47777328896b876314656427663695bc7b2c9be3f74dirk ThrowPPException(image_.quiet()); 4787b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk} 4797b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk 480e316d154e7b050fab78dbf86b33f0797594939cadirkMagick::ImagePerceptualHash::ImagePerceptualHash(void) 481e316d154e7b050fab78dbf86b33f0797594939cadirk : _channels() 482e316d154e7b050fab78dbf86b33f0797594939cadirk{ 483e316d154e7b050fab78dbf86b33f0797594939cadirk} 484e316d154e7b050fab78dbf86b33f0797594939cadirk 485e316d154e7b050fab78dbf86b33f0797594939cadirkMagick::ImagePerceptualHash::ImagePerceptualHash( 486e316d154e7b050fab78dbf86b33f0797594939cadirk const ImagePerceptualHash &imagePerceptualHash_) 487e316d154e7b050fab78dbf86b33f0797594939cadirk : _channels(imagePerceptualHash_._channels) 488e316d154e7b050fab78dbf86b33f0797594939cadirk{ 489e316d154e7b050fab78dbf86b33f0797594939cadirk} 490e316d154e7b050fab78dbf86b33f0797594939cadirk 491e316d154e7b050fab78dbf86b33f0797594939cadirkMagick::ImagePerceptualHash::ImagePerceptualHash(const std::string &hash_) 492e316d154e7b050fab78dbf86b33f0797594939cadirk : _channels() 493e316d154e7b050fab78dbf86b33f0797594939cadirk{ 494e316d154e7b050fab78dbf86b33f0797594939cadirk if (hash_.length() != 210) 495e316d154e7b050fab78dbf86b33f0797594939cadirk throw ErrorOption("Invalid hash length"); 496e316d154e7b050fab78dbf86b33f0797594939cadirk 497e316d154e7b050fab78dbf86b33f0797594939cadirk _channels.push_back(Magick::ChannelPerceptualHash(RedPixelChannel, 498e316d154e7b050fab78dbf86b33f0797594939cadirk hash_.substr(0, 70))); 499e316d154e7b050fab78dbf86b33f0797594939cadirk _channels.push_back(Magick::ChannelPerceptualHash(GreenPixelChannel, 500e316d154e7b050fab78dbf86b33f0797594939cadirk hash_.substr(70, 70))); 501e316d154e7b050fab78dbf86b33f0797594939cadirk _channels.push_back(Magick::ChannelPerceptualHash(BluePixelChannel, 502e316d154e7b050fab78dbf86b33f0797594939cadirk hash_.substr(140, 70))); 503e316d154e7b050fab78dbf86b33f0797594939cadirk} 504e316d154e7b050fab78dbf86b33f0797594939cadirk 505e316d154e7b050fab78dbf86b33f0797594939cadirkMagick::ImagePerceptualHash::~ImagePerceptualHash(void) 506e316d154e7b050fab78dbf86b33f0797594939cadirk{ 507e316d154e7b050fab78dbf86b33f0797594939cadirk} 508e316d154e7b050fab78dbf86b33f0797594939cadirk 509e316d154e7b050fab78dbf86b33f0797594939cadirkMagick::ImagePerceptualHash::operator std::string() const 510e316d154e7b050fab78dbf86b33f0797594939cadirk{ 511e316d154e7b050fab78dbf86b33f0797594939cadirk if (!isValid()) 512e316d154e7b050fab78dbf86b33f0797594939cadirk return(std::string()); 513e316d154e7b050fab78dbf86b33f0797594939cadirk 514e316d154e7b050fab78dbf86b33f0797594939cadirk return static_cast<std::string>(_channels[0]) + 515e316d154e7b050fab78dbf86b33f0797594939cadirk static_cast<std::string>(_channels[1]) + 516e316d154e7b050fab78dbf86b33f0797594939cadirk static_cast<std::string>(_channels[2]); 517e316d154e7b050fab78dbf86b33f0797594939cadirk} 518e316d154e7b050fab78dbf86b33f0797594939cadirk 519e316d154e7b050fab78dbf86b33f0797594939cadirkMagick::ChannelPerceptualHash Magick::ImagePerceptualHash::channel( 520e316d154e7b050fab78dbf86b33f0797594939cadirk const PixelChannel channel_) const 521e316d154e7b050fab78dbf86b33f0797594939cadirk{ 522e316d154e7b050fab78dbf86b33f0797594939cadirk for (std::vector<ChannelPerceptualHash>::const_iterator it = 523e316d154e7b050fab78dbf86b33f0797594939cadirk _channels.begin(); it != _channels.end(); ++it) 524e316d154e7b050fab78dbf86b33f0797594939cadirk { 525e316d154e7b050fab78dbf86b33f0797594939cadirk if (it->channel() == channel_) 526e316d154e7b050fab78dbf86b33f0797594939cadirk return(*it); 527e316d154e7b050fab78dbf86b33f0797594939cadirk } 528e316d154e7b050fab78dbf86b33f0797594939cadirk return(ChannelPerceptualHash()); 529e316d154e7b050fab78dbf86b33f0797594939cadirk} 530e316d154e7b050fab78dbf86b33f0797594939cadirk 531e316d154e7b050fab78dbf86b33f0797594939cadirkbool Magick::ImagePerceptualHash::isValid() const 532e316d154e7b050fab78dbf86b33f0797594939cadirk{ 533e316d154e7b050fab78dbf86b33f0797594939cadirk if (_channels.size() != 3) 534e316d154e7b050fab78dbf86b33f0797594939cadirk return(false); 535e316d154e7b050fab78dbf86b33f0797594939cadirk 536e316d154e7b050fab78dbf86b33f0797594939cadirk if (_channels[0].channel() != RedPixelChannel) 537e316d154e7b050fab78dbf86b33f0797594939cadirk return(false); 538e316d154e7b050fab78dbf86b33f0797594939cadirk 539e316d154e7b050fab78dbf86b33f0797594939cadirk if (_channels[1].channel() != GreenPixelChannel) 540e316d154e7b050fab78dbf86b33f0797594939cadirk return(false); 541e316d154e7b050fab78dbf86b33f0797594939cadirk 542e316d154e7b050fab78dbf86b33f0797594939cadirk if (_channels[2].channel() != BluePixelChannel) 543e316d154e7b050fab78dbf86b33f0797594939cadirk return(false); 544e316d154e7b050fab78dbf86b33f0797594939cadirk 545e316d154e7b050fab78dbf86b33f0797594939cadirk return(true); 546e316d154e7b050fab78dbf86b33f0797594939cadirk} 547e316d154e7b050fab78dbf86b33f0797594939cadirk 548e316d154e7b050fab78dbf86b33f0797594939cadirkdouble Magick::ImagePerceptualHash::sumSquaredDifferences( 549e316d154e7b050fab78dbf86b33f0797594939cadirk const ImagePerceptualHash &channelPerceptualHash_) 550e316d154e7b050fab78dbf86b33f0797594939cadirk{ 551e316d154e7b050fab78dbf86b33f0797594939cadirk double 552e316d154e7b050fab78dbf86b33f0797594939cadirk ssd; 553e316d154e7b050fab78dbf86b33f0797594939cadirk 554e316d154e7b050fab78dbf86b33f0797594939cadirk register ssize_t 555e316d154e7b050fab78dbf86b33f0797594939cadirk i; 556e316d154e7b050fab78dbf86b33f0797594939cadirk 557e316d154e7b050fab78dbf86b33f0797594939cadirk if (!isValid()) 558e316d154e7b050fab78dbf86b33f0797594939cadirk throw ErrorOption("instance is not valid"); 559e316d154e7b050fab78dbf86b33f0797594939cadirk if (!channelPerceptualHash_.isValid()) 560e316d154e7b050fab78dbf86b33f0797594939cadirk throw ErrorOption("channelPerceptualHash_ is not valid"); 561e316d154e7b050fab78dbf86b33f0797594939cadirk 562e316d154e7b050fab78dbf86b33f0797594939cadirk ssd=0.0; 563e316d154e7b050fab78dbf86b33f0797594939cadirk for (i=0; i<3; i++) 564e316d154e7b050fab78dbf86b33f0797594939cadirk { 565e316d154e7b050fab78dbf86b33f0797594939cadirk ssd+=_channels[i].sumSquaredDifferences(_channels[i]); 566e316d154e7b050fab78dbf86b33f0797594939cadirk } 567e316d154e7b050fab78dbf86b33f0797594939cadirk return(ssd); 568e316d154e7b050fab78dbf86b33f0797594939cadirk} 569e316d154e7b050fab78dbf86b33f0797594939cadirk 570e316d154e7b050fab78dbf86b33f0797594939cadirkMagick::ImagePerceptualHash::ImagePerceptualHash( 57177328896b876314656427663695bc7b2c9be3f74dirk const Image &image_) 572e316d154e7b050fab78dbf86b33f0797594939cadirk : _channels() 573e316d154e7b050fab78dbf86b33f0797594939cadirk{ 574e316d154e7b050fab78dbf86b33f0797594939cadirk MagickCore::ChannelPerceptualHash* 575e316d154e7b050fab78dbf86b33f0797594939cadirk channel_perceptual_hash; 576e316d154e7b050fab78dbf86b33f0797594939cadirk 577e316d154e7b050fab78dbf86b33f0797594939cadirk PixelTrait 578e316d154e7b050fab78dbf86b33f0797594939cadirk traits; 579e316d154e7b050fab78dbf86b33f0797594939cadirk 580e316d154e7b050fab78dbf86b33f0797594939cadirk GetPPException; 58177328896b876314656427663695bc7b2c9be3f74dirk channel_perceptual_hash=GetImagePerceptualHash(image_.constImage(), 58277328896b876314656427663695bc7b2c9be3f74dirk exceptionInfo); 583e316d154e7b050fab78dbf86b33f0797594939cadirk if (channel_perceptual_hash != (MagickCore::ChannelPerceptualHash *) NULL) 584e316d154e7b050fab78dbf86b33f0797594939cadirk { 58577328896b876314656427663695bc7b2c9be3f74dirk traits=GetPixelChannelTraits(image_.constImage(),RedPixelChannel); 586e316d154e7b050fab78dbf86b33f0797594939cadirk if ((traits & UpdatePixelTrait) != 0) 587e316d154e7b050fab78dbf86b33f0797594939cadirk _channels.push_back(Magick::ChannelPerceptualHash(RedPixelChannel, 588e316d154e7b050fab78dbf86b33f0797594939cadirk &channel_perceptual_hash[RedPixelChannel])); 58977328896b876314656427663695bc7b2c9be3f74dirk traits=GetPixelChannelTraits(image_.constImage(),GreenPixelChannel); 590e316d154e7b050fab78dbf86b33f0797594939cadirk if ((traits & UpdatePixelTrait) != 0) 591e316d154e7b050fab78dbf86b33f0797594939cadirk _channels.push_back(Magick::ChannelPerceptualHash(GreenPixelChannel, 592e316d154e7b050fab78dbf86b33f0797594939cadirk &channel_perceptual_hash[GreenPixelChannel])); 59377328896b876314656427663695bc7b2c9be3f74dirk traits=GetPixelChannelTraits(image_.constImage(),BluePixelChannel); 594e316d154e7b050fab78dbf86b33f0797594939cadirk if ((traits & UpdatePixelTrait) != 0) 595e316d154e7b050fab78dbf86b33f0797594939cadirk _channels.push_back(Magick::ChannelPerceptualHash(BluePixelChannel, 596e316d154e7b050fab78dbf86b33f0797594939cadirk &channel_perceptual_hash[BluePixelChannel])); 597e316d154e7b050fab78dbf86b33f0797594939cadirk channel_perceptual_hash=(MagickCore::ChannelPerceptualHash *) 598e316d154e7b050fab78dbf86b33f0797594939cadirk RelinquishMagickMemory(channel_perceptual_hash); 599e316d154e7b050fab78dbf86b33f0797594939cadirk } 6000e671c22538976a0aa0b21ae338e05f33a27cb10dirk ThrowPPException(image_.quiet()); 601e316d154e7b050fab78dbf86b33f0797594939cadirk} 602e316d154e7b050fab78dbf86b33f0797594939cadirk 6037b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirkMagick::ImageStatistics::ImageStatistics(void) 6047b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk : _channels() 6057b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk{ 6067b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk} 6077b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk 6087b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirkMagick::ImageStatistics::ImageStatistics( 6097b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk const ImageStatistics &imageStatistics_) 6107b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk : _channels(imageStatistics_._channels) 6117b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk{ 6127b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk} 6137b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk 6147b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirkMagick::ImageStatistics::~ImageStatistics(void) 6157b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk{ 6167b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk} 6177b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk 6187b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirkMagick::ChannelStatistics Magick::ImageStatistics::channel( 6197b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk const PixelChannel channel_) const 6207b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk{ 6217b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk for (std::vector<ChannelStatistics>::const_iterator it = _channels.begin(); 6227b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk it != _channels.end(); ++it) 6237b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk { 6247b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk if (it->channel() == channel_) 6257b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk return(*it); 6267b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk } 6277b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk return(ChannelStatistics()); 6287b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk} 6297b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk 63077328896b876314656427663695bc7b2c9be3f74dirkMagick::ImageStatistics::ImageStatistics(const Image &image_) 6317b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk : _channels() 6327b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk{ 6337b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk MagickCore::ChannelStatistics* 6347b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk channel_statistics; 6357b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk 6367b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk GetPPException; 63777328896b876314656427663695bc7b2c9be3f74dirk channel_statistics=GetImageStatistics(image_.constImage(),exceptionInfo); 6387b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk if (channel_statistics != (MagickCore::ChannelStatistics *) NULL) 6397b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk { 6407b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk register ssize_t 6417b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk i; 6427b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk 64377328896b876314656427663695bc7b2c9be3f74dirk for (i=0; i < (ssize_t) GetPixelChannels(image_.constImage()); i++) 6447b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk { 64577328896b876314656427663695bc7b2c9be3f74dirk PixelChannel channel=GetPixelChannelChannel(image_.constImage(),i); 64677328896b876314656427663695bc7b2c9be3f74dirk PixelTrait traits=GetPixelChannelTraits(image_.constImage(),channel); 6477b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk if (traits == UndefinedPixelTrait) 6487b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk continue; 6497b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk if ((traits & UpdatePixelTrait) == 0) 6507b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk continue; 6517b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk _channels.push_back(Magick::ChannelStatistics(channel, 6527b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk &channel_statistics[channel])); 6537b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk } 6547b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk _channels.push_back(Magick::ChannelStatistics(CompositePixelChannel, 6557b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk &channel_statistics[CompositePixelChannel])); 6567b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk channel_statistics=(MagickCore::ChannelStatistics *) RelinquishMagickMemory( 6577b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk channel_statistics); 6587b6b37ee0712fc684e19cf3b7472cf9063b3d2f5dirk } 65977328896b876314656427663695bc7b2c9be3f74dirk ThrowPPException(image_.quiet()); 66057f71289ef12fb275c908972156e7e397d9e07bbcristy} 661