From 4ed18986105418d3f682d96929603c68f412cefd Mon Sep 17 00:00:00 2001 From: Cristy Date: Sat, 12 Dec 2015 09:50:30 -0500 Subject: [PATCH] IsImagesEqual() returns false if the images are not equal, whereas SetImageColorMetric() returns the color error metric --- MagickCore/compare.c | 123 ++++++++++++++++++++++++++++++++++++++++--- MagickCore/compare.h | 3 +- 2 files changed, 117 insertions(+), 9 deletions(-) diff --git a/MagickCore/compare.c b/MagickCore/compare.c index a29f4efff..026d360fa 100644 --- a/MagickCore/compare.c +++ b/MagickCore/compare.c @@ -121,7 +121,7 @@ static size_t GetImageChannels(const Image *image) if ((traits & UpdatePixelTrait) != 0) channels++; } - return(channels == 0 ? 1 : channels); + return(channels == 0 ? (size_t) 1 : channels); } static inline MagickBooleanType ValidateImageMorphology( @@ -1526,7 +1526,114 @@ MagickExport double *GetImageDistortions(Image *image, % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % -% IsImagesEqual() measures the difference between colors at each pixel +% IsImagesEqual() compare the pixels of two images and returns immediately +% if any pixel is not identical. +% +% The format of the IsImagesEqual method is: +% +% MagickBooleanType IsImagesEqual(const Image *image, +% const Image *reconstruct_image,ExceptionInfo *exception) +% +% A description of each parameter follows. +% +% o image: the image. +% +% o reconstruct_image: the reconstruct image. +% +% o exception: return any errors or warnings in this structure. +% +*/ +MagickExport MagickBooleanType IsImagesEqual(const Image *image, + const Image *reconstruct_image,ExceptionInfo *exception) +{ + CacheView + *image_view, + *reconstruct_view; + + size_t + columns, + rows; + + ssize_t + y; + + assert(image != (Image *) NULL); + assert(image->signature == MagickCoreSignature); + assert(reconstruct_image != (const Image *) NULL); + assert(reconstruct_image->signature == MagickCoreSignature); + if (ValidateImageMorphology(image,reconstruct_image) == MagickFalse) + ThrowBinaryException(ImageError,"ImageMorphologyDiffers",image->filename); + rows=MagickMax(image->rows,reconstruct_image->rows); + columns=MagickMax(image->columns,reconstruct_image->columns); + image_view=AcquireVirtualCacheView(image,exception); + reconstruct_view=AcquireVirtualCacheView(reconstruct_image,exception); + for (y=0; y < (ssize_t) rows; y++) + { + register const Quantum + *magick_restrict p, + *magick_restrict q; + + register ssize_t + x; + + p=GetCacheViewVirtualPixels(image_view,0,y,columns,1,exception); + q=GetCacheViewVirtualPixels(reconstruct_view,0,y,columns,1,exception); + if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL)) + break; + for (x=0; x < (ssize_t) columns; x++) + { + register ssize_t + i; + + if (GetPixelReadMask(image,p) == 0) + { + p+=GetPixelChannels(image); + q+=GetPixelChannels(reconstruct_image); + continue; + } + for (i=0; i < (ssize_t) GetPixelChannels(image); i++) + { + double + distance; + + PixelChannel channel=GetPixelChannelChannel(image,i); + PixelTrait traits=GetPixelChannelTraits(image,channel); + PixelTrait reconstruct_traits=GetPixelChannelTraits(reconstruct_image, + channel); + if ((traits == UndefinedPixelTrait) || + (reconstruct_traits == UndefinedPixelTrait) || + ((reconstruct_traits & UpdatePixelTrait) == 0)) + continue; + distance=fabs(p[i]-(double) GetPixelChannel(reconstruct_image, + channel,q)); + if (distance >= MagickEpsilon) + break; + } + if (i < (ssize_t) GetPixelChannels(image)) + break; + p+=GetPixelChannels(image); + q+=GetPixelChannels(reconstruct_image); + } + if (x < (ssize_t) columns) + break; + } + reconstruct_view=DestroyCacheView(reconstruct_view); + image_view=DestroyCacheView(image_view); + return(y < (ssize_t) rows ? MagickFalse : MagickTrue); +} + +/* +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % +% % +% % +% S e t I m a g e C o l o r M e t r i c % +% % +% % +% % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% SetImageColorMetric() measures the difference between colors at each pixel % location of two images. A value other than 0 means the colors match % exactly. Otherwise an error measure is computed by summing over all % pixels in an image the distance squared in RGB space between each image @@ -1550,9 +1657,9 @@ MagickExport double *GetImageDistortions(Image *image, % image->normalized_mean_error, suggests the images are very similar in % spatial layout and color. % -% The format of the IsImagesEqual method is: +% The format of the SetImageColorMetric method is: % -% MagickBooleanType IsImagesEqual(Image *image, +% MagickBooleanType SetImageColorMetric(Image *image, % const Image *reconstruct_image,ExceptionInfo *exception) % % A description of each parameter follows. @@ -1564,22 +1671,22 @@ MagickExport double *GetImageDistortions(Image *image, % o exception: return any errors or warnings in this structure. % */ -MagickExport MagickBooleanType IsImagesEqual(Image *image, +MagickExport MagickBooleanType SetImageColorMetric(Image *image, const Image *reconstruct_image,ExceptionInfo *exception) { CacheView *image_view, *reconstruct_view; - MagickBooleanType - status; - double area, maximum_error, mean_error, mean_error_per_pixel; + MagickBooleanType + status; + size_t columns, rows; diff --git a/MagickCore/compare.h b/MagickCore/compare.h index 94a234434..9a507a3c8 100644 --- a/MagickCore/compare.h +++ b/MagickCore/compare.h @@ -51,7 +51,8 @@ extern MagickExport Image extern MagickExport MagickBooleanType GetImageDistortion(Image *,const Image *,const MetricType,double *, ExceptionInfo *), - IsImagesEqual(Image *,const Image *,ExceptionInfo *); + IsImagesEqual(const Image *,const Image *,ExceptionInfo *), + SetImageColorMetric(Image *,const Image *,ExceptionInfo *); #if defined(__cplusplus) || defined(c_plusplus) } -- 2.40.0