Commit 602c43695 for imagemagick.org

commit 602c43695a0bb7e60a58b62f6257959407681492
Author: Dirk Lemstra <dirk@lemstra.org>
Date:   Sun Nov 16 19:42:32 2025 +0100

    Improved the jpeg coder by calculating the range only once instead of every pixel channel.

diff --git a/coders/jpeg.c b/coders/jpeg.c
index f917f3e64..5570424a2 100644
--- a/coders/jpeg.c
+++ b/coders/jpeg.c
@@ -256,26 +256,20 @@ static MagickBooleanType IsJPEG(const unsigned char *magick,const size_t length)
 %
 */

-static inline Quantum JPEGGetQuantum(
-  const struct jpeg_decompress_struct *jpeg_info,const JSAMPLE *p)
+static inline Quantum JPEGGetQuantum(const struct jpeg_decompress_struct *jpeg_info,
+  QuantumAny range,const JSAMPLE *p)
 {
   if (jpeg_info->data_precision == 8)
     return ScaleCharToQuantum(*p);
   else if (jpeg_info->data_precision == 16)
     return ScaleShortToQuantum(*(unsigned short *) p);
   else if (jpeg_info->data_precision < 8)
-    {
-      QuantumAny range=GetQuantumRange(jpeg_info->data_precision);
-      return ScaleAnyToQuantum(*p,range);
-    }
+    return ScaleAnyToQuantum(*p,range);
   else
-    {
-      QuantumAny range=GetQuantumRange(jpeg_info->data_precision);
-      return ScaleAnyToQuantum(*(unsigned short *) p,range);
-    }
+    return ScaleAnyToQuantum(*(unsigned short *) p,range);
 }

-static boolean FillInputBuffer(j_decompress_ptr compress_info)
+static boolean FillInputBuffer(const j_decompress_ptr compress_info)
 {
   SourceManager
     *source;
@@ -834,7 +828,7 @@ static void JPEGSourceManager(j_decompress_ptr compress_info,Image *image)
   source->image=image;
 }

-static void JPEGSetImageQuality(struct jpeg_decompress_struct *jpeg_info,
+static void JPEGSetImageQuality(const struct jpeg_decompress_struct *jpeg_info,
   Image *image)
 {
   image->quality=UndefinedCompressionQuality;
@@ -967,7 +961,8 @@ static void JPEGSetImageQuality(struct jpeg_decompress_struct *jpeg_info,
   }
 }

-static void JPEGSetImageSamplingFactor(struct jpeg_decompress_struct *jpeg_info,  Image *image,ExceptionInfo *exception)
+static void JPEGSetImageSamplingFactor(const struct jpeg_decompress_struct *jpeg_info,
+  Image *image,ExceptionInfo *exception)
 {
   char
     sampling_factor[MagickPathExtent];
@@ -1097,6 +1092,9 @@ static Image *ReadOneJPEGImage(const ImageInfo *image_info,
   MemoryInfo
     *memory_info;

+  QuantumAny
+    range;
+
   size_t
     bytes_per_pixel,
     max_memory_to_use,
@@ -1466,6 +1464,7 @@ static Image *ReadOneJPEGImage(const ImageInfo *image_info,
           image->colormap[i].alpha=(MagickRealType) OpaqueAlpha;
         }
     }
+  range=GetQuantumRange(jpeg_info->data_precision);
   for (y=0; y < (ssize_t) image->rows; y++)
   {
     JDIMENSION
@@ -1521,7 +1520,8 @@ static Image *ReadOneJPEGImage(const ImageInfo *image_info,
           Quantum
             index;

-          unsigned short pixel;
+          unsigned short
+            pixel;

           if (jpeg_info->data_precision > 8)
             pixel=(*(unsigned short *) p);
@@ -1543,13 +1543,13 @@ static Image *ReadOneJPEGImage(const ImageInfo *image_info,
         */
         for (x=0; x < (ssize_t) image->columns; x++)
         {
-          SetPixelCyan(image,QuantumRange-JPEGGetQuantum(jpeg_info,p),q);
+          SetPixelCyan(image,QuantumRange-JPEGGetQuantum(jpeg_info,range,p),q);
           p+=(ptrdiff_t) bytes_per_pixel;
-          SetPixelMagenta(image,QuantumRange-JPEGGetQuantum(jpeg_info,p),q);
+          SetPixelMagenta(image,QuantumRange-JPEGGetQuantum(jpeg_info,range,p),q);
           p+=(ptrdiff_t) bytes_per_pixel;
-          SetPixelYellow(image,QuantumRange-JPEGGetQuantum(jpeg_info,p),q);
+          SetPixelYellow(image,QuantumRange-JPEGGetQuantum(jpeg_info,range,p),q);
           p+=(ptrdiff_t) bytes_per_pixel;
-          SetPixelBlack(image,QuantumRange-JPEGGetQuantum(jpeg_info,p),q);
+          SetPixelBlack(image,QuantumRange-JPEGGetQuantum(jpeg_info,range,p),q);
           p+=(ptrdiff_t) bytes_per_pixel;
           SetPixelAlpha(image,OpaqueAlpha,q);
           q+=(ptrdiff_t) GetPixelChannels(image);
@@ -1563,11 +1563,11 @@ static Image *ReadOneJPEGImage(const ImageInfo *image_info,
         */
         for (x=0; x < (ssize_t) image->columns; x++)
         {
-          SetPixelRed(image,JPEGGetQuantum(jpeg_info,p),q);
+          SetPixelRed(image,JPEGGetQuantum(jpeg_info,range,p),q);
           p+=(ptrdiff_t) bytes_per_pixel;
-          SetPixelGreen(image,JPEGGetQuantum(jpeg_info,p),q);
+          SetPixelGreen(image,JPEGGetQuantum(jpeg_info,range,p),q);
           p+=(ptrdiff_t) bytes_per_pixel;
-          SetPixelBlue(image,JPEGGetQuantum(jpeg_info,p),q);
+          SetPixelBlue(image,JPEGGetQuantum(jpeg_info,range,p),q);
           p+=(ptrdiff_t) bytes_per_pixel;
           SetPixelAlpha(image,OpaqueAlpha,q);
           q+=(ptrdiff_t) GetPixelChannels(image);
@@ -2359,22 +2359,16 @@ static char **SamplingFactorToList(const char *text)
 }

 static inline void JPEGSetSample(const struct jpeg_compress_struct *jpeg_info,
-  const Quantum pixel,JSAMPLE *q)
+  const Quantum pixel,QuantumAny range,JSAMPLE *q)
 {
   if (jpeg_info->data_precision == 8)
     *q=(JSAMPLE) ScaleQuantumToChar(pixel);
   else if (jpeg_info->data_precision == 16)
     (*(unsigned short *) q)=(unsigned short) ScaleQuantumToShort(pixel);
   else if (jpeg_info->data_precision < 8)
-    {
-      QuantumAny range=GetQuantumRange(jpeg_info->data_precision);
-      *q=(JSAMPLE) ScaleQuantumToAny(pixel,range);
-    }
+    *q=(JSAMPLE) ScaleQuantumToAny(pixel,range);
   else
-    {
-      QuantumAny range=GetQuantumRange(jpeg_info->data_precision);
-      (*(unsigned short *) q)=(unsigned short) ScaleQuantumToAny(pixel,range);
-    }
+    (*(unsigned short *) q)=(unsigned short) ScaleQuantumToAny(pixel,range);
 }

 static MagickBooleanType WriteJPEGImage_(const ImageInfo *image_info,
@@ -2416,6 +2410,9 @@ static MagickBooleanType WriteJPEGImage_(const ImageInfo *image_info,
   MemoryInfo
     *memory_info;

+  QuantumAny
+    range;
+
   ssize_t
     bytes_per_pixel,
     i,
@@ -3017,6 +3014,7 @@ static MagickBooleanType WriteJPEGImage_(const ImageInfo *image_info,
         jps_image=DestroyImage(jps_image);
       return(MagickFalse);
     }
+  range=GetQuantumRange(jpeg_info->data_precision);
   for (y=0; y < (ssize_t) image->rows; y++)
   {
     const Quantum
@@ -3044,8 +3042,7 @@ static MagickBooleanType WriteJPEGImage_(const ImageInfo *image_info,
         */
         for (x=0; x < (ssize_t) image->columns; x++)
         {
-          JPEGSetSample(jpeg_info,ClampToQuantum(GetPixelLuma(image,p)),
-            q);
+          JPEGSetSample(jpeg_info,ClampToQuantum(GetPixelLuma(image,p)),range,q);
           q+=(ptrdiff_t) bytes_per_pixel;
           p+=(ptrdiff_t) GetPixelChannels(image);
         }
@@ -3062,16 +3059,16 @@ static MagickBooleanType WriteJPEGImage_(const ImageInfo *image_info,
             Convert DirectClass packets to contiguous CMYK scanlines.
           */
           JPEGSetSample(jpeg_info,(Quantum) ((QuantumRange-
-            GetPixelCyan(image,p))),q);
+            GetPixelCyan(image,p))),range,q);
           q+=(ptrdiff_t) bytes_per_pixel;
           JPEGSetSample(jpeg_info,(Quantum) ((QuantumRange-
-            GetPixelMagenta(image,p))),q);
+            GetPixelMagenta(image,p))),range,q);
           q+=(ptrdiff_t) bytes_per_pixel;
           JPEGSetSample(jpeg_info,(Quantum) ((QuantumRange-
-            GetPixelYellow(image,p))),q);
+            GetPixelYellow(image,p))),range,q);
           q+=(ptrdiff_t) bytes_per_pixel;
           JPEGSetSample(jpeg_info,(Quantum) ((QuantumRange-
-            GetPixelBlack(image,p))),q);
+            GetPixelBlack(image,p))),range,q);
           q+=(ptrdiff_t) bytes_per_pixel;
           p+=(ptrdiff_t) GetPixelChannels(image);
         }
@@ -3084,11 +3081,11 @@ static MagickBooleanType WriteJPEGImage_(const ImageInfo *image_info,
         */
         for (x=0; x < (ssize_t) image->columns; x++)
         {
-          JPEGSetSample(jpeg_info,GetPixelRed(image,p),q);
+          JPEGSetSample(jpeg_info,GetPixelRed(image,p),range,q);
           q+=(ptrdiff_t) bytes_per_pixel;
-          JPEGSetSample(jpeg_info,GetPixelGreen(image,p),q);
+          JPEGSetSample(jpeg_info,GetPixelGreen(image,p),range,q);
           q+=(ptrdiff_t) bytes_per_pixel;
-          JPEGSetSample(jpeg_info,GetPixelBlue(image,p),q);
+          JPEGSetSample(jpeg_info,GetPixelBlue(image,p),range,q);
           q+=(ptrdiff_t) bytes_per_pixel;
           p+=(ptrdiff_t) GetPixelChannels(image);
         }