Blame SOURCES/rhbz1633602-quantize.patch

b9c1e2
diff -up ImageMagick-6.7.8-9/magick/quantize.c.quantize ImageMagick-6.7.8-9/magick/quantize.c
b9c1e2
--- ImageMagick-6.7.8-9/magick/quantize.c.quantize	2012-08-09 02:12:12.000000000 +0200
b9c1e2
+++ ImageMagick-6.7.8-9/magick/quantize.c	2018-10-23 14:16:48.484639782 +0200
b9c1e2
@@ -333,7 +333,9 @@ static MagickBooleanType
b9c1e2
   SetGrayscaleImage(Image *);
b9c1e2
 
b9c1e2
 static size_t
b9c1e2
-  DefineImageColormap(Image *,CubeInfo *,NodeInfo *);
b9c1e2
+  DefineImageColormap(Image *,CubeInfo *,NodeInfo *),
b9c1e2
+  QuantizeErrorFlatten(const Image *,const CubeInfo *,const NodeInfo *,
b9c1e2
+    const ssize_t,const size_t,MagickRealType *);
b9c1e2
 
b9c1e2
 static void
b9c1e2
   ClosestColor(const Image *,CubeInfo *,const NodeInfo *),
b9c1e2
@@ -2882,6 +2884,66 @@ MagickExport MagickBooleanType QuantizeI
b9c1e2
 %                                                                             %
b9c1e2
 %                                                                             %
b9c1e2
 %                                                                             %
b9c1e2
++   Q u a n t i z e E r r o r F l a t t e n                                   %
b9c1e2
+%                                                                             %
b9c1e2
+%                                                                             %
b9c1e2
+%                                                                             %
b9c1e2
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
b9c1e2
+%
b9c1e2
+%  QuantizeErrorFlatten() traverses the color cube and flattens the quantization
b9c1e2
+%  error into a sorted array.  This accelerates the color reduction process.
b9c1e2
+%
b9c1e2
+%  Contributed by Yoya.
b9c1e2
+%
b9c1e2
+%  The format of the QuantizeImages method is:
b9c1e2
+%
b9c1e2
+%      size_t QuantizeErrorFlatten(const Image *image,const CubeInfo *cube_info,
b9c1e2
+%        const NodeInfo *node_info,const ssize_t offset,const size_t extent,
b9c1e2
+%        MagickRealType *quantize_error)
b9c1e2
+%
b9c1e2
+%  A description of each parameter follows.
b9c1e2
+%
b9c1e2
+%    o image: the image.
b9c1e2
+%
b9c1e2
+%    o cube_info: A pointer to the Cube structure.
b9c1e2
+%
b9c1e2
+%    o node_info: pointer to node in color cube tree that is current pointer.
b9c1e2
+%
b9c1e2
+%    o offset: quantize error offset.
b9c1e2
+%
b9c1e2
+%    o extent: quantize error offset maximum limit.
b9c1e2
+%
b9c1e2
+%    o quantize_error: the quantization error vector.
b9c1e2
+%
b9c1e2
+*/
b9c1e2
+static size_t QuantizeErrorFlatten(const Image *image,const CubeInfo *cube_info,
b9c1e2
+  const NodeInfo *node_info,const ssize_t offset,const size_t extent,
b9c1e2
+  MagickRealType *quantize_error)
b9c1e2
+{
b9c1e2
+  register ssize_t
b9c1e2
+    i;
b9c1e2
+
b9c1e2
+  size_t
b9c1e2
+    n,
b9c1e2
+    number_children;
b9c1e2
+
b9c1e2
+  if (offset >= (ssize_t) extent)
b9c1e2
+    return(0);
b9c1e2
+  quantize_error[offset]=node_info->quantize_error;
b9c1e2
+  n=1;
b9c1e2
+  number_children=cube_info->associate_alpha == MagickFalse ? 8UL : 16UL;
b9c1e2
+  for (i=0; i < (ssize_t) number_children ; i++)
b9c1e2
+    if (node_info->child[i] != (NodeInfo *) NULL)
b9c1e2
+      n+=QuantizeErrorFlatten(image,cube_info,node_info->child[i],offset+n,
b9c1e2
+        extent,quantize_error);
b9c1e2
+  return(n);
b9c1e2
+}
b9c1e2
+ 
b9c1e2
+/*
b9c1e2
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
b9c1e2
+%                                                                             %
b9c1e2
+%                                                                             %
b9c1e2
+%                                                                             %
b9c1e2
 +   R e d u c e                                                               %
b9c1e2
 %                                                                             %
b9c1e2
 %                                                                             %
b9c1e2
@@ -2988,6 +3050,22 @@ static void Reduce(const Image *image,Cu
b9c1e2
 %    o cube_info: A pointer to the Cube structure.
b9c1e2
 %
b9c1e2
 */
b9c1e2
+
b9c1e2
+static int MagickRealTypeCompare(const void *error_p,const void *error_q)
b9c1e2
+{
b9c1e2
+  MagickRealType
b9c1e2
+    *p,
b9c1e2
+    *q;
b9c1e2
+
b9c1e2
+  p=(MagickRealType *) error_p;
b9c1e2
+  q=(MagickRealType *) error_q;
b9c1e2
+  if (*p > *q)
b9c1e2
+    return(1);
b9c1e2
+  if (fabs((double) (*q-*p)) <= MagickEpsilon)
b9c1e2
+    return(0);
b9c1e2
+  return(-1);
b9c1e2
+}
b9c1e2
+
b9c1e2
 static void ReduceImageColors(const Image *image,CubeInfo *cube_info)
b9c1e2
 {
b9c1e2
 #define ReduceImageTag  "Reduce/Image"
579df2
@@ -3002,6 +3080,29 @@ static void ReduceImageColors(const Imag
b9c1e2
     span;
b9c1e2
 
b9c1e2
   cube_info->next_threshold=0.0;
b9c1e2
+  if (cube_info->colors > cube_info->maximum_colors)
b9c1e2
+    {
b9c1e2
+      MagickRealType
b9c1e2
+        *quantize_error;
b9c1e2
+
b9c1e2
+      /*
b9c1e2
+        Enable rapid reduction of the number of unique colors.
b9c1e2
+      */
b9c1e2
+      quantize_error=(MagickRealType *) AcquireQuantumMemory(cube_info->nodes,
b9c1e2
+        sizeof(*quantize_error));
b9c1e2
+      if (quantize_error != (MagickRealType *) NULL)
b9c1e2
+        {
b9c1e2
+          (void) QuantizeErrorFlatten(image,cube_info,cube_info->root,0,
b9c1e2
+            cube_info->nodes,quantize_error);
b9c1e2
+          qsort(quantize_error,cube_info->nodes,sizeof(MagickRealType),
b9c1e2
+            MagickRealTypeCompare);
579df2
+          if (cube_info->nodes > (110*(cube_info->maximum_colors+1)/100))
579df2
+            cube_info->next_threshold=quantize_error[cube_info->nodes-110*
579df2
+              (cube_info->maximum_colors+1)/100];
b9c1e2
+          quantize_error=(MagickRealType *) RelinquishMagickMemory(
b9c1e2
+            quantize_error);
b9c1e2
+        }
b9c1e2
+  }
b9c1e2
   for (span=cube_info->colors; cube_info->colors > cube_info->maximum_colors; )
b9c1e2
   {
b9c1e2
     cube_info->pruning_threshold=cube_info->next_threshold;