Commit 63fdb7105 for imagemagick.org
commit 63fdb7105a0f54c10432e6ea146cc578a38b655e
Author: Cristy <urban-warrior@imagemagick.org>
Date: Fri Apr 18 12:02:42 2025 -0400
correct MEPP metric
diff --git a/MagickCore/compare.c b/MagickCore/compare.c
index 72b14d262..91802b724 100644
--- a/MagickCore/compare.c
+++ b/MagickCore/compare.c
@@ -618,14 +618,12 @@ static MagickBooleanType GetMeanAbsoluteDistortion(const Image *image,
MagickBooleanType
status;
- ssize_t
- j;
-
size_t
columns,
rows;
ssize_t
+ j,
y;
status=MagickTrue;
@@ -731,44 +729,54 @@ static MagickBooleanType GetMeanErrorPerPixel(Image *image,
*image_view,
*reconstruct_view;
- MagickBooleanType
- status;
-
double
- area,
- maximum_error,
- mean_error;
+ area = 0.0,
+ maximum_error = MagickMinimumValue;
+
+ MagickBooleanType
+ status = MagickTrue;
size_t
columns,
rows;
ssize_t
+ j,
y;
- status=MagickTrue;
- area=0.0;
- maximum_error=0.0;
- mean_error=0.0;
SetImageDistortionBounds(image,reconstruct_image,&columns,&rows);
image_view=AcquireVirtualCacheView(image,exception);
reconstruct_view=AcquireVirtualCacheView(reconstruct_image,exception);
+#if defined(MAGICKCORE_OPENMP_SUPPORT)
+ #pragma omp parallel for schedule(static) shared(status) \
+ magick_number_threads(image,image,rows,1)
+#endif
for (y=0; y < (ssize_t) rows; y++)
{
+ double
+ channel_distortion[MaxPixelChannels+1],
+ local_maximum = MagickMinimumValue;
+
const Quantum
*magick_restrict p,
*magick_restrict q;
+ size_t
+ local_area = 0;
+
ssize_t
x;
+ if (status == MagickFalse)
+ continue;
p=GetCacheViewVirtualPixels(image_view,0,y,columns,1,exception);
q=GetCacheViewVirtualPixels(reconstruct_view,0,y,columns,1,exception);
if ((p == (const Quantum *) NULL) || (q == (const Quantum *) NULL))
{
status=MagickFalse;
- break;
+ continue;
}
+ (void) memset(channel_distortion,0,sizeof(channel_distortion));
for (x=0; x < (ssize_t) columns; x++)
{
double
@@ -806,23 +814,35 @@ static MagickBooleanType GetMeanErrorPerPixel(Image *image,
else
distance=QuantumScale*fabs(Sa*(double) p[i]-Da*(double)
GetPixelChannel(reconstruct_image,channel,q));
- distortion[i]+=distance;
- distortion[CompositePixelChannel]+=distance;
- mean_error+=distance*distance;
- if (distance > maximum_error)
- maximum_error=distance;
- area++;
+ channel_distortion[i]+=distance;
+ channel_distortion[CompositePixelChannel]+=distance;
+ if (distance > local_maximum)
+ local_maximum=distance;
}
+ local_area++;
p+=(ptrdiff_t) GetPixelChannels(image);
q+=(ptrdiff_t) GetPixelChannels(reconstruct_image);
}
+#if defined(MAGICKCORE_OPENMP_SUPPORT)
+ #pragma omp critical (MagickCore_GetMeanAbsoluteError)
+#endif
+ {
+ area+=local_area;
+ for (j=0; j <= MaxPixelChannels; j++)
+ distortion[j]+=channel_distortion[j];
+ if (local_maximum > maximum_error)
+ maximum_error=local_maximum;
+ }
}
reconstruct_view=DestroyCacheView(reconstruct_view);
image_view=DestroyCacheView(image_view);
area=PerceptibleReciprocal(area);
- image->error.mean_error_per_pixel=area*distortion[CompositePixelChannel];
- image->error.normalized_mean_error=area*QuantumScale*QuantumScale*mean_error;
- image->error.normalized_maximum_error=QuantumScale*maximum_error;
+ for (j=0; j <= MaxPixelChannels; j++)
+ distortion[j]*=area;
+ distortion[CompositePixelChannel]/=(double) GetImageChannels(image);
+ image->error.mean_error_per_pixel=distortion[CompositePixelChannel];
+ image->error.normalized_mean_error=distortion[CompositePixelChannel];
+ image->error.normalized_maximum_error=maximum_error;
return(status);
}
diff --git a/MagickWand/compare.c b/MagickWand/compare.c
index 0e294cef6..6dbe0d62d 100644
--- a/MagickWand/compare.c
+++ b/MagickWand/compare.c
@@ -1315,7 +1315,7 @@ WandExport MagickBooleanType CompareImagesCommand(ImageInfo *image_info,
case MeanErrorPerPixelErrorMetric:
{
(void) FormatLocaleFile(stderr,"%.*g (%.*g, %.*g)",
- GetMagickPrecision(),distortion,
+ GetMagickPrecision(),QuantumRange*distortion,
GetMagickPrecision(),image->error.normalized_mean_error,
GetMagickPrecision(),image->error.normalized_maximum_error);
break;