Commit 35db3e46d for imagemagick.org

commit 35db3e46d67e75d6ca5726de6d805e1e8b02fceb
Author: Dirk Lemstra <dirk@lemstra.org>
Date:   Sat Nov 14 12:33:07 2026 +0100

    Preserve full-range neutral values in luminance calculations.

diff --git a/MagickCore/colorspace.c b/MagickCore/colorspace.c
index 9d0f973b0..8c239631d 100644
--- a/MagickCore/colorspace.c
+++ b/MagickCore/colorspace.c
@@ -977,9 +977,7 @@ static MagickBooleanType sRGBTransformImage(Image *image,
           MagickRealType
             gray;

-          gray=0.212656*DecodePixelGamma(GetPixelRed(image,q))+0.715158*
-            DecodePixelGamma(GetPixelGreen(image,q))+0.072186*
-            DecodePixelGamma(GetPixelBlue(image,q));
+          gray=GetPixelLuminance(image,q);
           SetPixelGray(image,ClampToQuantum(gray),q);
           q+=(ptrdiff_t) GetPixelChannels(image);
         }
@@ -1035,8 +1033,7 @@ static MagickBooleanType sRGBTransformImage(Image *image,
           MagickRealType
             gray;

-          gray=0.212656*(double) GetPixelRed(image,q)+0.715158*(double)
-            GetPixelGreen(image,q)+0.072186*(double) GetPixelBlue(image,q);
+          gray=GetPixelLuma(image,q);
           SetPixelGray(image,ClampToQuantum(gray),q);
           q+=(ptrdiff_t) GetPixelChannels(image);
         }
diff --git a/MagickCore/pixel-accessor.h b/MagickCore/pixel-accessor.h
index 3ac47aa81..ed81746e5 100644
--- a/MagickCore/pixel-accessor.h
+++ b/MagickCore/pixel-accessor.h
@@ -249,6 +249,12 @@ static inline MagickRealType GetPixelInfoLuma(
   MagickRealType
     intensity;

+  if ((pixel->red == pixel->green) && (pixel->green == pixel->blue))
+    {
+      if (pixel->colorspace == sRGBColorspace)
+        return(pixel->red);
+      return(EncodePixelGamma(pixel->red));
+    }
   if (pixel->colorspace == sRGBColorspace)
     {
       intensity=(MagickRealType) (0.212656*pixel->red+0.715158*pixel->green+
@@ -267,6 +273,12 @@ static inline MagickRealType GetPixelInfoLuminance(
   MagickRealType
     intensity;

+  if ((pixel->red == pixel->green) && (pixel->green == pixel->blue))
+    {
+      if (pixel->colorspace != sRGBColorspace)
+        return(pixel->red);
+      return(DecodePixelGamma(pixel->red));
+    }
   if (pixel->colorspace != sRGBColorspace)
     {
       intensity=(MagickRealType) (0.212656*pixel->red+0.715158*pixel->green+
@@ -295,12 +307,18 @@ static inline MagickRealType GetPixelLuma(
   const Image *magick_restrict image,const Quantum *magick_restrict pixel)
 {
   MagickRealType
-    intensity;
+    intensity,
+    red,
+    green,
+    blue;

-  intensity=
-    0.212656*(MagickRealType) pixel[image->channel_map[RedPixelChannel].offset]+
-    0.715158*(MagickRealType) pixel[image->channel_map[GreenPixelChannel].offset]+
-    0.072186*(MagickRealType) pixel[image->channel_map[BluePixelChannel].offset];
+  red=(MagickRealType) pixel[image->channel_map[RedPixelChannel].offset];
+  green=(MagickRealType) pixel[image->channel_map[GreenPixelChannel].offset];
+  blue=(MagickRealType) pixel[image->channel_map[BluePixelChannel].offset];
+  if ((red == green) && (green == blue))
+    intensity=red;
+  else
+    intensity=0.212656*red+0.715158*green+0.072186*blue;
   return(intensity);
 }

@@ -308,22 +326,30 @@ static inline MagickRealType GetPixelLuminance(
   const Image *magick_restrict image,const Quantum *magick_restrict pixel)
 {
   MagickRealType
-    intensity;
+    intensity,
+    red,
+    green,
+    blue;

   if (image->colorspace != sRGBColorspace)
     {
-      intensity=
-        0.212656*(MagickRealType) pixel[image->channel_map[RedPixelChannel].offset]+
-        0.715158*(MagickRealType) pixel[image->channel_map[GreenPixelChannel].offset]+
-        0.072186*(MagickRealType) pixel[image->channel_map[BluePixelChannel].offset];
-      return(intensity);
+      red=(MagickRealType) pixel[image->channel_map[RedPixelChannel].offset];
+      green=(MagickRealType) pixel[image->channel_map[GreenPixelChannel].offset];
+      blue=(MagickRealType) pixel[image->channel_map[BluePixelChannel].offset];
+    }
+  else
+    {
+      red=DecodePixelGamma((MagickRealType)
+        pixel[image->channel_map[RedPixelChannel].offset]);
+      green=DecodePixelGamma((MagickRealType)
+        pixel[image->channel_map[GreenPixelChannel].offset]);
+      blue=DecodePixelGamma((MagickRealType)
+        pixel[image->channel_map[BluePixelChannel].offset]);
     }
-  intensity=(MagickRealType) (0.212656*DecodePixelGamma((MagickRealType)
-    pixel[image->channel_map[RedPixelChannel].offset])+0.715158*
-    DecodePixelGamma((MagickRealType)
-    pixel[image->channel_map[GreenPixelChannel].offset])+0.072186*
-    DecodePixelGamma((MagickRealType)
-    pixel[image->channel_map[BluePixelChannel].offset]));
+  if ((red == green) && (green == blue))
+    intensity=red;
+  else
+    intensity=0.212656*red+0.715158*green+0.072186*blue;
   return(intensity);
 }