]> granicus.if.org Git - imagemagick/blobdiff - MagickCore/quantize.c
https://github.com/ImageMagick/ImageMagick/issues/1584
[imagemagick] / MagickCore / quantize.c
index 310bf15e559a4be393fe7b9556a8fe0cd2df1577..76995a4433ecd15e846703065049de1978f0686f 100644 (file)
@@ -17,7 +17,7 @@
 %                              July 1992                                      %
 %                                                                             %
 %                                                                             %
-%  Copyright 1999-2018 ImageMagick Studio LLC, a non-profit organization      %
+%  Copyright 1999-2019 ImageMagick Studio LLC, a non-profit organization      %
 %  dedicated to making software imaging solutions freely available.           %
 %                                                                             %
 %  You may not use this file except in compliance with the License.  You may  %
@@ -1950,8 +1950,7 @@ static MagickBooleanType DitherImage(Image *image,CubeInfo *cube_info,
   /*
     Distribute quantization error along a Hilbert curve.
   */
-  (void) memset(cube_info->error,0,ErrorQueueLength*
-    sizeof(*cube_info->error));
+  (void) memset(cube_info->error,0,ErrorQueueLength*sizeof(*cube_info->error));
   cube_info->x=0;
   cube_info->y=0;
   i=MagickMax((ssize_t) image->columns,(ssize_t) image->rows);
@@ -2053,8 +2052,7 @@ static CubeInfo *GetCubeInfo(const QuantizeInfo *quantize_info,
   /*
     Initialize color cache.
   */
-  (void) memset(cube_info->cache,(-1),sizeof(*cube_info->cache)*
-    length);
+  (void) memset(cube_info->cache,(-1),sizeof(*cube_info->cache)*length);
   /*
     Distribute weights along a curve of exponential decay.
   */
@@ -2201,10 +2199,8 @@ MagickExport MagickBooleanType GetImageQuantizeError(Image *image,
     mean_error,
     mean_error_per_pixel;
 
-  size_t
-    index;
-
   ssize_t
+    index,
     y;
 
   assert(image != (Image *) NULL);
@@ -2235,7 +2231,7 @@ MagickExport MagickBooleanType GetImageQuantizeError(Image *image,
       break;
     for (x=0; x < (ssize_t) image->columns; x++)
     {
-      index=GetPixelIndex(image,p);
+      index=(ssize_t) GetPixelIndex(image,p);
       if (image->alpha_trait == BlendPixelTrait)
         {
           alpha=(double) (QuantumScale*GetPixelAlpha(image,p));
@@ -2351,8 +2347,8 @@ MagickExport MagickBooleanType PosterizeImage(Image *image,const size_t levels,
   const DitherMethod dither_method,ExceptionInfo *exception)
 {
 #define PosterizeImageTag  "Posterize/Image"
-#define PosterizePixel(pixel) (Quantum) (QuantumRange*(MagickRound( \
-  QuantumScale*pixel*(levels-1)))/MagickMax((ssize_t) levels-1,1))
+#define PosterizePixel(pixel) ClampToQuantum((MagickRealType) QuantumRange*( \
+  MagickRound(QuantumScale*pixel*(levels-1)))/MagickMax((ssize_t) levels-1,1))
 
   CacheView
     *image_view;
@@ -2676,7 +2672,8 @@ MagickExport MagickBooleanType QuantizeImage(const QuantizeInfo *quantize_info,
       if (SetImageGray(image,exception) != MagickFalse)
         (void) SetGrayscaleImage(image,exception);
     }
-  if ((image->storage_class == PseudoClass) &&
+  if ((quantize_info->dither_method == NoDitherMethod) &&
+      (image->storage_class == PseudoClass) &&
       (image->colors <= maximum_colors))
     {
       if ((quantize_info->colorspace != UndefinedColorspace) &&
@@ -2715,13 +2712,10 @@ MagickExport MagickBooleanType QuantizeImage(const QuantizeInfo *quantize_info,
   if (status != MagickFalse)
     {
       /*
-        Reduce the number of colors in the image if it contains more than the
-        maximum, otherwise we can disable dithering to improve the performance.
+        Reduce the number of colors in the image.
       */
       if (cube_info->colors > cube_info->maximum_colors)
         ReduceImageColors(image,cube_info);
-      else
-        cube_info->quantize_info->dither_method=NoDitherMethod;
       status=AssignImageColors(image,cube_info,exception);
     }
   DestroyCubeInfo(cube_info);
@@ -3296,6 +3290,10 @@ static int IntensityCompare(const void *x,const void *y)
   color_2=(PixelInfo *) y;
   intensity=GetPixelInfoIntensity((const Image *) NULL,color_1)-
     GetPixelInfoIntensity((const Image *) NULL,color_2);
+  if (intensity > (double) INT_MAX)
+    intensity=(double) INT_MAX;
+  if (intensity < (double) INT_MIN)
+    intensity=(double) INT_MIN;
   return((int) intensity);
 }
 
@@ -3318,6 +3316,9 @@ static MagickBooleanType SetGrayscaleImage(Image *image,
   register ssize_t
     i;
 
+  size_t
+    extent;
+
   ssize_t
     *colormap_index,
     j,
@@ -3327,19 +3328,15 @@ static MagickBooleanType SetGrayscaleImage(Image *image,
   assert(image->signature == MagickCoreSignature);
   if (image->type != GrayscaleType)
     (void) TransformImageColorspace(image,GRAYColorspace,exception);
-  if (image->storage_class == PseudoClass)
-    colormap_index=(ssize_t *) AcquireQuantumMemory(image->colors+1,
-      sizeof(*colormap_index));
-  else
-    colormap_index=(ssize_t *) AcquireQuantumMemory(MaxColormapSize+1,
-      sizeof(*colormap_index));
+  extent=MagickMax(image->colors+1,MagickMax(MaxColormapSize,MaxMap+1));
+  colormap_index=(ssize_t *) AcquireQuantumMemory(extent,
+    sizeof(*colormap_index));
   if (colormap_index == (ssize_t *) NULL)
     ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
       image->filename);
   if (image->storage_class != PseudoClass)
     {
-      (void) memset(colormap_index,(-1),MaxColormapSize*
-        sizeof(*colormap_index));
+      (void) memset(colormap_index,(-1),extent*sizeof(*colormap_index));
       if (AcquireImageColormap(image,MaxColormapSize,exception) == MagickFalse)
         {
           colormap_index=(ssize_t *) RelinquishMagickMemory(colormap_index);
@@ -3401,6 +3398,7 @@ static MagickBooleanType SetGrayscaleImage(Image *image,
       }
       image_view=DestroyCacheView(image_view);
     }
+  (void) memset(colormap_index,0,extent*sizeof(*colormap_index));
   for (i=0; i < (ssize_t) image->colors; i++)
     image->colormap[i].alpha=(double) i;
   qsort((void *) image->colormap,image->colors,sizeof(PixelInfo),