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