Coverage Report

Created: 2026-04-01 07:49

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/graphicsmagick/magick/quantize.c
Line
Count
Source
1
/*
2
% Copyright (C) 2003-2020 GraphicsMagick Group
3
% Copyright (C) 2002 ImageMagick Studio
4
% Copyright 1991-1999 E. I. du Pont de Nemours and Company
5
%
6
% This program is covered by multiple licenses, which are described in
7
% Copyright.txt. You should have received a copy of Copyright.txt with this
8
% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
9
%
10
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
11
%                                                                             %
12
%                                                                             %
13
%                                                                             %
14
%           QQQ   U   U   AAA   N   N  TTTTT  IIIII   ZZZZZ  EEEEE            %
15
%          Q   Q  U   U  A   A  NN  N    T      I        ZZ  E                %
16
%          Q   Q  U   U  AAAAA  N N N    T      I      ZZZ   EEEEE            %
17
%          Q  QQ  U   U  A   A  N  NN    T      I     ZZ     E                %
18
%           QQQQ   UUU   A   A  N   N    T    IIIII   ZZZZZ  EEEEE            %
19
%                                                                             %
20
%                                                                             %
21
%         Methods to Reduce the Number of Unique Colors in an Image           %
22
%                                                                             %
23
%                                                                             %
24
%                           Software Design                                   %
25
%                             John Cristy                                     %
26
%                              July 1992                                      %
27
%                                                                             %
28
%                                                                             %
29
%                                                                             %
30
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
31
%
32
%  Realism in computer graphics typically requires using 24 bits/pixel to
33
%  generate an image.  Yet many graphic display devices do not contain the
34
%  amount of memory necessary to match the spatial and color resolution of
35
%  the human eye.  The Quantize methods takes a 24 bit image and reduces
36
%  the number of colors so it can be displayed on raster device with less
37
%  bits per pixel.  In most instances, the quantized image closely
38
%  resembles the original reference image.
39
%
40
%  A reduction of colors in an image is also desirable for image
41
%  transmission and real-time animation.
42
%
43
%  QuantizeImage() takes a standard RGB or monochrome images and quantizes
44
%  them down to some fixed number of colors.
45
%
46
%  For purposes of color allocation, an image is a set of n pixels, where
47
%  each pixel is a point in RGB space.  RGB space is a 3-dimensional
48
%  vector space, and each pixel, Pi,  is defined by an ordered triple of
49
%  red, green, and blue coordinates, (Ri, Gi, Bi).
50
%
51
%  Each primary color component (red, green, or blue) represents an
52
%  intensity which varies linearly from 0 to a maximum value, Cmax, which
53
%  corresponds to full saturation of that color.  Color allocation is
54
%  defined over a domain consisting of the cube in RGB space with opposite
55
%  vertices at (0,0,0) and (Cmax, Cmax, Cmax).  QUANTIZE requires Cmax =
56
%  255.
57
%
58
%  The algorithm maps this domain onto a tree in which each node
59
%  represents a cube within that domain.  In the following discussion
60
%  these cubes are defined by the coordinate of two opposite vertices:
61
%  The vertex nearest the origin in RGB space and the vertex farthest from
62
%  the origin.
63
%
64
%  The tree's root node represents the the entire domain, (0,0,0) through
65
%  (Cmax,Cmax,Cmax).  Each lower level in the tree is generated by
66
%  subdividing one node's cube into eight smaller cubes of equal size.
67
%  This corresponds to bisecting the parent cube with planes passing
68
%  through the midpoints of each edge.
69
%
70
%  The basic algorithm operates in three phases: Classification,
71
%  Reduction, and Assignment.  Classification builds a color description
72
%  tree for the image.  Reduction collapses the tree until the number it
73
%  represents, at most, the number of colors desired in the output image.
74
%  Assignment defines the output image's color map and sets each pixel's
75
%  color by restorage_class in the reduced tree.  Our goal is to minimize
76
%  the numerical discrepancies between the original colors and quantized
77
%  colors (quantization error).
78
%
79
%  Classification begins by initializing a color description tree of
80
%  sufficient depth to represent each possible input color in a leaf.
81
%  However, it is impractical to generate a fully-formed color description
82
%  tree in the storage_class phase for realistic values of Cmax.  If
83
%  colors components in the input image are quantized to k-bit precision,
84
%  so that Cmax= 2k-1, the tree would need k levels below the root node to
85
%  allow representing each possible input color in a leaf.  This becomes
86
%  prohibitive because the tree's total number of nodes is 1 +
87
%  sum(i=1, k, 8k).
88
%
89
%  A complete tree would require 19,173,961 nodes for k = 8, Cmax = 255.
90
%  Therefore, to avoid building a fully populated tree, QUANTIZE: (1)
91
%  Initializes data structures for nodes only as they are needed;  (2)
92
%  Chooses a maximum depth for the tree as a function of the desired
93
%  number of colors in the output image (currently log2(colormap size)).
94
%
95
%  For each pixel in the input image, storage_class scans downward from
96
%  the root of the color description tree.  At each level of the tree it
97
%  identifies the single node which represents a cube in RGB space
98
%  containing the pixel's color.  It updates the following data for each
99
%  such node:
100
%
101
%    n1: Number of pixels whose color is contained in the RGB cube which
102
%    this node represents;
103
%
104
%    n2: Number of pixels whose color is not represented in a node at
105
%    lower depth in the tree;  initially,  n2 = 0 for all nodes except
106
%    leaves of the tree.
107
%
108
%    Sr, Sg, Sb: Sums of the red, green, and blue component values for all
109
%    pixels not classified at a lower depth. The combination of these sums
110
%    and n2  will ultimately characterize the mean color of a set of
111
%    pixels represented by this node.
112
%
113
%    E: The distance squared in RGB space between each pixel contained
114
%    within a node and the nodes' center.  This represents the
115
%    quantization error for a node.
116
%
117
%  Reduction repeatedly prunes the tree until the number of nodes with n2
118
%  > 0 is less than or equal to the maximum number of colors allowed in
119
%  the output image.  On any given iteration over the tree, it selects
120
%  those nodes whose E count is minimal for pruning and merges their color
121
%  statistics upward. It uses a pruning threshold, Ep, to govern node
122
%  selection as follows:
123
%
124
%    Ep = 0
125
%    while number of nodes with (n2 > 0) > required maximum number of colors
126
%      prune all nodes such that E <= Ep
127
%      Set Ep to minimum E in remaining nodes
128
%
129
%  This has the effect of minimizing any quantization error when merging
130
%  two nodes together.
131
%
132
%  When a node to be pruned has offspring, the pruning procedure invokes
133
%  itself recursively in order to prune the tree from the leaves upward.
134
%  n2,  Sr, Sg,  and  Sb in a node being pruned are always added to the
135
%  corresponding data in that node's parent.  This retains the pruned
136
%  node's color characteristics for later averaging.
137
%
138
%  For each node, n2 pixels exist for which that node represents the
139
%  smallest volume in RGB space containing those pixel's colors.  When n2
140
%  > 0 the node will uniquely define a color in the output image. At the
141
%  beginning of reduction,  n2 = 0  for all nodes except a the leaves of
142
%  the tree which represent colors present in the input image.
143
%
144
%  The other pixel count, n1, indicates the total number of colors within
145
%  the cubic volume which the node represents.  This includes n1 - n2
146
%  pixels whose colors should be defined by nodes at a lower level in the
147
%  tree.
148
%
149
%  Assignment generates the output image from the pruned tree.  The output
150
%  image consists of two parts: (1)  A color map, which is an array of
151
%  color descriptions (RGB triples) for each color present in the output
152
%  image;  (2)  A pixel array, which represents each pixel as an index
153
%  into the color map array.
154
%
155
%  First, the assignment phase makes one pass over the pruned color
156
%  description tree to establish the image's color map.  For each node
157
%  with n2  > 0, it divides Sr, Sg, and Sb by n2 .  This produces the mean
158
%  color of all pixels that classify no lower than this node.  Each of
159
%  these colors becomes an entry in the color map.
160
%
161
%  Finally,  the assignment phase reclassifies each pixel in the pruned
162
%  tree to identify the deepest node containing the pixel's color.  The
163
%  pixel's value in the pixel array becomes the index of this node's mean
164
%  color in the color map.
165
%
166
%  This method is based on a similar algorithm written by Paul Raveling.
167
%
168
%
169
*/
170

171
/*
172
  Include declarations.
173
*/
174
#include "magick/studio.h"
175
#include "magick/analyze.h"
176
#include "magick/color.h"
177
#include "magick/colormap.h"
178
#include "magick/enhance.h"
179
#include "magick/monitor.h"
180
#include "magick/pixel_cache.h"
181
#include "magick/quantize.h"
182
#include "magick/utility.h"
183

184
/*
185
  Define declarations.
186
*/
187
124M
#define CacheShift  (QuantumDepth-6)
188
1.36G
#define ExceptionQueueLength  16
189
598k
#define MaxNodes  266817
190
9.74G
#define MaxTreeDepth  8
191
16.2k
#define NodesInAList  1536
192
193
195M
#define ColorToNodeId(red,green,blue,index) ((unsigned int) \
194
195M
            (((ScaleQuantumToChar(red) >> index) & 0x01) << 2 | \
195
195M
             ((ScaleQuantumToChar(green) >> index) & 0x01) << 1 | \
196
195M
             ((ScaleQuantumToChar(blue) >> index) & 0x01)))
197

198
/*
199
  Typedef declarations.
200
*/
201
#if QuantumDepth > 16 && defined(HAVE_LONG_DOUBLE_WIDER)
202
  typedef long double ErrorSumType;
203
#else
204
  typedef double ErrorSumType;
205
#endif
206
207
typedef struct _NodeInfo
208
{
209
  struct _NodeInfo
210
    *parent,
211
    *child[MaxTreeDepth];
212
213
  double
214
    number_unique;
215
216
  double  /* was ErrorSumType */
217
    total_red,
218
    total_green,
219
    total_blue;
220
221
  ErrorSumType
222
    quantize_error;
223
224
  unsigned long
225
    color_number;
226
227
  unsigned char
228
    id,
229
    level;
230
} NodeInfo;
231
232
typedef struct _Nodes
233
{
234
  NodeInfo
235
    *nodes;
236
237
  struct _Nodes
238
    *next;
239
} Nodes;
240
241
typedef struct _CubeInfo
242
{
243
  NodeInfo
244
    *root;
245
246
  unsigned long
247
    colors;
248
249
  DoublePixelPacket
250
    color;
251
252
  double  /* was ErrorSumType */
253
    distance;
254
255
  ErrorSumType
256
    pruning_threshold,
257
    next_threshold;
258
259
  unsigned long
260
    nodes,
261
    free_nodes,
262
    color_number;
263
264
  NodeInfo
265
    *next_node;
266
267
  Nodes
268
    *node_queue;
269
270
  long
271
    *cache;
272
273
  DoublePixelPacket
274
    error[ExceptionQueueLength];
275
276
  double
277
    weights[ExceptionQueueLength];
278
279
  const QuantizeInfo
280
    *quantize_info;
281
282
  long
283
    x,
284
    y;
285
286
  unsigned long
287
    depth;
288
} CubeInfo;
289

290
/*
291
  Method prototypes.
292
*/
293
static void
294
  ClosestColor(Image *,CubeInfo *,const NodeInfo *);
295
296
static NodeInfo
297
  *GetNodeInfo(CubeInfo *,const unsigned int,const unsigned int,NodeInfo *);
298
299
static unsigned int
300
  DitherImage(CubeInfo *,Image *);
301
302
static void
303
  DefineImageColormap(Image *,NodeInfo *),
304
  HilbertCurve(CubeInfo *,Image *,const unsigned long,const unsigned int),
305
  PruneLevel(CubeInfo *,const NodeInfo *),
306
  PruneToCubeDepth(CubeInfo *,const NodeInfo *),
307
  ReduceImageColors(const char *filename,CubeInfo *,const unsigned long,ExceptionInfo *);
308

309
/*
310
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
311
%                                                                             %
312
%                                                                             %
313
%                                                                             %
314
+   A s s i g n I m a g e C o l o r s                                         %
315
%                                                                             %
316
%                                                                             %
317
%                                                                             %
318
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
319
%
320
%  AssignImageColors() generates the output image from the pruned tree.  The
321
%  output image consists of two parts: (1)  A color map, which is an array
322
%  of color descriptions (RGB triples) for each color present in the
323
%  output image;  (2)  A pixel array, which represents each pixel as an
324
%  index into the color map array.
325
%
326
%  First, the assignment phase makes one pass over the pruned color
327
%  description tree to establish the image's color map.  For each node
328
%  with n2  > 0, it divides Sr, Sg, and Sb by n2 .  This produces the mean
329
%  color of all pixels that classify no lower than this node.  Each of
330
%  these colors becomes an entry in the color map.
331
%
332
%  Finally,  the assignment phase reclassifies each pixel in the pruned
333
%  tree to identify the deepest node containing the pixel's color.  The
334
%  pixel's value in the pixel array becomes the index of this node's mean
335
%  color in the color map.
336
%
337
%  The format of the AssignImageColors() method is:
338
%
339
%      unsigned int AssignImageColors(CubeInfo *cube_info,Image *image)
340
%
341
%  A description of each parameter follows.
342
%
343
%    o cube_info: A pointer to the Cube structure.
344
%
345
%    o image: Specifies a pointer to an Image structure;  returned from
346
%      ReadImage.
347
%
348
%
349
*/
350
static MagickPassFail AssignImageColors(CubeInfo *cube_info,Image *image)
351
15.9k
{
352
60.3k
#define AssignImageText "[%s] Assign colors..."
353
354
15.9k
  unsigned int
355
15.9k
    dither;
356
357
15.9k
  unsigned int
358
15.9k
    is_grayscale,
359
15.9k
    is_monochrome;
360
361
15.9k
  MagickPassFail
362
15.9k
    status=MagickPass;
363
364
  /*
365
    Allocate image colormap.
366
  */
367
15.9k
  if (!AllocateImageColormap(image,cube_info->colors))
368
0
    ThrowBinaryException3(ResourceLimitError,MemoryAllocationFailed,
369
15.9k
                          UnableToQuantizeImage);
370
15.9k
  image->colors=0;
371
15.9k
  is_grayscale=image->is_grayscale;
372
15.9k
  is_monochrome=image->is_monochrome;
373
15.9k
  DefineImageColormap(image,cube_info->root);
374
15.9k
  if (cube_info->quantize_info->colorspace == TransparentColorspace)
375
396
    image->storage_class=DirectClass;
376
  /*
377
    Create a reduced color image.
378
  */
379
15.9k
  dither=cube_info->quantize_info->dither;
380
15.9k
  if (dither)
381
15.2k
    dither=DitherImage(cube_info,image);
382
15.9k
  if (!dither)
383
628
    {
384
628
      long
385
628
        y;
386
387
      /*
388
        FIXME: Use OpenMP?
389
      */
390
140k
      for (y=0; y < (long) image->rows; y++)
391
139k
        {
392
139k
          IndexPacket
393
139k
            index;
394
395
139k
          long
396
139k
            count;
397
398
139k
          register IndexPacket
399
139k
            *indexes;
400
401
139k
          register long
402
139k
            i,
403
139k
            x;
404
405
139k
          register const NodeInfo
406
139k
            *node_info;
407
408
139k
          register PixelPacket
409
139k
            *q;
410
411
139k
          unsigned int
412
139k
            id;
413
414
139k
          q=GetImagePixels(image,0,y,image->columns,1);
415
139k
          if (q == (PixelPacket *) NULL)
416
0
            {
417
0
              status=MagickFail;
418
0
              break;
419
0
            }
420
139k
          indexes=AccessMutableIndexes(image);
421
2.48M
          for (x=0; x < (long) image->columns; x+=count)
422
2.34M
            {
423
              /*
424
                Identify the deepest node containing the pixel's color.
425
              */
426
20.3M
              for (count=1; (x+count) < (long) image->columns; count++)
427
20.1M
                if (NotColorMatch(q,q+count))
428
2.20M
                  break;
429
2.34M
              node_info=cube_info->root;
430
8.87M
              for (index=MaxTreeDepth-1; (long) index > 0; index--)
431
8.69M
                {
432
8.69M
                  id=ColorToNodeId(q->red,q->green,q->blue,index);
433
8.69M
                  if (node_info->child[id] == (NodeInfo *) NULL)
434
2.16M
                    break;
435
6.53M
                  node_info=node_info->child[id];
436
6.53M
                }
437
              /*
438
                Find closest color among siblings and their children.
439
              */
440
2.34M
              cube_info->color.red=q->red;
441
2.34M
              cube_info->color.green=q->green;
442
2.34M
              cube_info->color.blue=q->blue;
443
2.34M
              cube_info->distance=3.0*(MaxRGBDouble+1.0)*(MaxRGBDouble+1.0);
444
2.34M
              ClosestColor(image,cube_info,node_info->parent);
445
2.34M
              index=(IndexPacket) cube_info->color_number;
446
22.6M
              for (i=0; i < count; i++)
447
20.3M
                {
448
20.3M
                  if (image->storage_class == PseudoClass)
449
19.4M
                    indexes[x+i]=index;
450
20.3M
                  if (!cube_info->quantize_info->measure_error)
451
20.3M
                    {
452
20.3M
                      q->red=image->colormap[index].red;
453
20.3M
                      q->green=image->colormap[index].green;
454
20.3M
                      q->blue=image->colormap[index].blue;
455
20.3M
                    }
456
20.3M
                  q++;
457
20.3M
                }
458
2.34M
            }
459
139k
          if (!SyncImagePixels(image))
460
0
            {
461
0
              status=MagickFail;
462
0
              break;
463
0
            }
464
139k
          if (QuantumTick(y,image->rows))
465
60.3k
            if (!MagickMonitorFormatted(y,image->rows,&image->exception,
466
60.3k
                                        AssignImageText,image->filename))
467
0
              {
468
0
                status=MagickFail;
469
0
                break;
470
0
              }
471
139k
        }
472
628
    }
473
15.9k
  if ((cube_info->quantize_info->number_colors == 2) &&
474
69
      (IsGrayColorspace(cube_info->quantize_info->colorspace)))
475
0
    {
476
0
      PixelPacket
477
0
        *q;
478
479
0
      Quantum
480
0
        intensity;
481
482
0
      long
483
0
        i;
484
485
      /*
486
        Monochrome image.
487
      */
488
0
      is_monochrome=True;
489
0
      q=image->colormap;
490
0
      for (i=(long) image->colors; i > 0; i--)
491
0
        {
492
0
          intensity=(Quantum) (PixelIntensityToQuantum(q) <
493
0
                               (MaxRGB/2) ? 0 : MaxRGB);
494
0
          q->red=intensity;
495
0
          q->green=intensity;
496
0
          q->blue=intensity;
497
0
          q++;
498
0
        }
499
0
    }
500
15.9k
  if (cube_info->quantize_info->measure_error)
501
0
    (void) GetImageQuantizeError(image);
502
15.9k
  status &= SyncImage(image);
503
15.9k
  image->is_grayscale=is_grayscale;
504
15.9k
  image->is_monochrome=is_monochrome;
505
15.9k
  return(status);
506
15.9k
}
507

508
/*
509
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
510
%                                                                             %
511
%                                                                             %
512
%                                                                             %
513
+   C l a s s i f y I m a g e C o l o r s                                     %
514
%                                                                             %
515
%                                                                             %
516
%                                                                             %
517
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
518
%
519
%  ClassifyImageColors() begins by initializing a color description tree
520
%  of sufficient depth to represent each possible input color in a leaf.
521
%  However, it is impractical to generate a fully-formed color
522
%  description tree in the storage_class phase for realistic values of
523
%  Cmax.  If colors components in the input image are quantized to k-bit
524
%  precision, so that Cmax= 2k-1, the tree would need k levels below the
525
%  root node to allow representing each possible input color in a leaf.
526
%  This becomes prohibitive because the tree's total number of nodes is
527
%  1 + sum(i=1,k,8k).
528
%
529
%  A complete tree would require 19,173,961 nodes for k = 8, Cmax = 255.
530
%  Therefore, to avoid building a fully populated tree, QUANTIZE: (1)
531
%  Initializes data structures for nodes only as they are needed;  (2)
532
%  Chooses a maximum depth for the tree as a function of the desired
533
%  number of colors in the output image (currently log2(colormap size)).
534
%
535
%  For each pixel in the input image, storage_class scans downward from
536
%  the root of the color description tree.  At each level of the tree it
537
%  identifies the single node which represents a cube in RGB space
538
%  containing It updates the following data for each such node:
539
%
540
%    n1 : Number of pixels whose color is contained in the RGB cube
541
%    which this node represents;
542
%
543
%    n2 : Number of pixels whose color is not represented in a node at
544
%    lower depth in the tree;  initially,  n2 = 0 for all nodes except
545
%    leaves of the tree.
546
%
547
%    Sr, Sg, Sb : Sums of the red, green, and blue component values for
548
%    all pixels not classified at a lower depth. The combination of
549
%    these sums and n2  will ultimately characterize the mean color of a
550
%    set of pixels represented by this node.
551
%
552
%    E: The distance squared in RGB space between each pixel contained
553
%    within a node and the nodes' center.  This represents the quantization
554
%    error for a node.
555
%
556
%  The format of the ClassifyImageColors() method is:
557
%
558
%      unsigned int ClassifyImageColorsCubeInfo *cube_info,const Image *image,
559
%        ExceptionInfo *exception)
560
%
561
%  A description of each parameter follows.
562
%
563
%    o cube_info: A pointer to the Cube structure.
564
%
565
%    o image: Specifies a pointer to an Image structure;  returned from
566
%      ReadImage.
567
%
568
%
569
*/
570
571
static MagickPassFail ClassifyImageColors(CubeInfo *cube_info,const Image *image,
572
  ExceptionInfo *exception)
573
15.9k
{
574
169k
#define ClassifyImageText "[%s] Classify colors..."
575
576
15.9k
  double
577
15.9k
    bisect;
578
579
15.9k
  DoublePixelPacket
580
15.9k
    mid,
581
15.9k
    pixel;
582
583
15.9k
  long
584
15.9k
    count,
585
15.9k
    y;
586
587
15.9k
  NodeInfo
588
15.9k
    *node_info;
589
590
15.9k
  register long
591
15.9k
    x;
592
593
15.9k
  register const PixelPacket
594
15.9k
    *p;
595
596
15.9k
  unsigned long
597
15.9k
    index,
598
15.9k
    level;
599
600
15.9k
  unsigned int
601
15.9k
    id;
602
603
15.9k
  MagickPassFail
604
15.9k
    status=MagickPass;
605
606
  /*
607
    Classify the first 256 colors to a tree depth of 8.
608
  */
609
431k
  for (y=0; (y < (long) image->rows) && (cube_info->colors < 256); y++)
610
415k
  {
611
415k
    p=AcquireImagePixels(image,0,y,image->columns,1,exception);
612
415k
    if (p == (const PixelPacket *) NULL)
613
37
      {
614
37
        status=MagickFail;
615
37
        break;
616
37
      }
617
415k
    if (cube_info->nodes > MaxNodes)
618
0
      {
619
        /*
620
          Prune one level if the color tree is too large.
621
        */
622
0
        PruneLevel(cube_info,cube_info->root);
623
0
        cube_info->depth--;
624
0
      }
625
12.9M
    for (x=0; x < (long) image->columns; x+=count)
626
12.5M
    {
627
      /*
628
        Start at the root and descend the color cube tree.
629
      */
630
182M
      for (count=1; (x+count) < (long) image->columns; count++)
631
182M
        if (NotColorMatch(p,p+count))
632
12.1M
          break;
633
12.5M
      index=MaxTreeDepth-1;
634
12.5M
      bisect=(MaxRGBDouble+1.0)/2.0;
635
12.5M
      mid.red=MaxRGBDouble/2.0;
636
12.5M
      mid.green=MaxRGBDouble/2.0;
637
12.5M
      mid.blue=MaxRGBDouble/2.0;
638
12.5M
      node_info=cube_info->root;
639
112M
      for (level=1; level <= 8; level++)
640
100M
      {
641
100M
        bisect/=2;
642
100M
        id=ColorToNodeId(p->red,p->green,p->blue,index);
643
100M
        mid.red+=id & 4 ? bisect : -bisect;
644
100M
        mid.green+=id & 2 ? bisect : -bisect;
645
100M
        mid.blue+=id & 1 ? bisect : -bisect;
646
100M
        if (node_info->child[id] == (NodeInfo *) NULL)
647
1.10M
          {
648
            /*
649
              Set colors of new node to contain pixel.
650
            */
651
1.10M
            node_info->child[id]=GetNodeInfo(cube_info,id,level,node_info);
652
1.10M
            if (node_info->child[id] == (NodeInfo *) NULL)
653
0
              {
654
0
                ThrowException3(exception,ResourceLimitError,
655
0
                                MemoryAllocationFailed,UnableToQuantizeImage);
656
0
                status=MagickFail;
657
0
                break;
658
0
              }
659
1.10M
            if (level == MaxTreeDepth)
660
251k
              cube_info->colors++;
661
1.10M
          }
662
        /*
663
          Approximate the quantization error represented by this node.
664
        */
665
100M
        node_info=node_info->child[id];
666
100M
        pixel.red=p->red-mid.red;
667
100M
        pixel.green=p->green-mid.green;
668
100M
        pixel.blue=p->blue-mid.blue;
669
100M
        node_info->quantize_error+=count*pixel.red*pixel.red+
670
100M
          count*pixel.green*pixel.green+count*pixel.blue*pixel.blue;
671
100M
        cube_info->root->quantize_error+=node_info->quantize_error;
672
100M
        index--;
673
100M
      }
674
12.5M
      if (status == MagickFail)
675
0
        break;
676
      /*
677
        Sum RGB for this leaf for later derivation of the mean cube color.
678
      */
679
12.5M
      node_info->number_unique+=count;
680
12.5M
      node_info->total_red+=(double) count*p->red;
681
12.5M
      node_info->total_green+=(double) count*p->green;
682
12.5M
      node_info->total_blue+=(double) count*p->blue;
683
12.5M
      p+=count;
684
12.5M
    }
685
415k
    if (QuantumTick(y,image->rows))
686
111k
      if (!MagickMonitorFormatted(y,image->rows,exception,
687
111k
                                  ClassifyImageText,image->filename))
688
0
        {
689
0
          status=MagickFail;
690
0
          break;
691
0
        }
692
415k
  }
693
15.9k
  if ((status == MagickFail) || (y == (long) image->rows))
694
15.2k
    return status;
695
  /*
696
    More than 256 colors;  classify to the cube_info->depth tree depth.
697
  */
698
662
  PruneToCubeDepth(cube_info,cube_info->root);
699
183k
  for ( ; y < (long) image->rows; y++)
700
182k
  {
701
182k
    p=AcquireImagePixels(image,0,y,image->columns,1,exception);
702
182k
    if (p == (const PixelPacket *) NULL)
703
0
      {
704
0
        status=MagickFail;
705
0
        break;
706
0
      }
707
182k
    if (cube_info->nodes > MaxNodes)
708
0
      {
709
        /*
710
          Prune one level if the color tree is too large.
711
        */
712
0
        PruneLevel(cube_info,cube_info->root);
713
0
        cube_info->depth--;
714
0
      }
715
13.2M
    for (x=0; x < (long) image->columns; x+=count)
716
13.0M
    {
717
      /*
718
        Start at the root and descend the color cube tree.
719
      */
720
58.0M
      for (count=1; (x+count) < (long) image->columns; count++)
721
57.8M
        if (NotColorMatch(p,p+count))
722
12.8M
          break;
723
13.0M
      index=MaxTreeDepth-1;
724
13.0M
      bisect=(MaxRGBDouble+1.0)/2.0;
725
13.0M
      mid.red=MaxRGBDouble/2.0;
726
13.0M
      mid.green=MaxRGBDouble/2.0;
727
13.0M
      mid.blue=MaxRGBDouble/2.0;
728
13.0M
      node_info=cube_info->root;
729
89.7M
      for (level=1; level <= cube_info->depth; level++)
730
76.7M
      {
731
76.7M
        bisect/=2.0;
732
76.7M
        id=ColorToNodeId(p->red,p->green,p->blue,index);
733
76.7M
        mid.red+=id & 4 ? bisect : -bisect;
734
76.7M
        mid.green+=id & 2 ? bisect : -bisect;
735
76.7M
        mid.blue+=id & 1 ? bisect : -bisect;
736
76.7M
        if (node_info->child[id] == (NodeInfo *) NULL)
737
544k
          {
738
            /*
739
              Set colors of new node to contain pixel.
740
            */
741
544k
            node_info->child[id]=GetNodeInfo(cube_info,id,level,node_info);
742
544k
            if (node_info->child[id] == (NodeInfo *) NULL)
743
0
              {
744
0
                ThrowException3(exception,ResourceLimitError,
745
0
                                MemoryAllocationFailed,UnableToQuantizeImage);
746
0
                status=MagickFail;
747
0
                break;
748
0
              }
749
544k
            if (level == cube_info->depth)
750
401k
              cube_info->colors++;
751
544k
          }
752
        /*
753
          Approximate the quantization error represented by this node.
754
        */
755
76.7M
        node_info=node_info->child[id];
756
76.7M
        pixel.red=p->red-mid.red;
757
76.7M
        pixel.green=p->green-mid.green;
758
76.7M
        pixel.blue=p->blue-mid.blue;
759
76.7M
        node_info->quantize_error+=count*pixel.red*pixel.red+
760
76.7M
          count*pixel.green*pixel.green+count*pixel.blue*pixel.blue;
761
76.7M
        cube_info->root->quantize_error+=node_info->quantize_error;
762
76.7M
        index--;
763
76.7M
      }
764
13.0M
      if (status == MagickFail)
765
0
        break;
766
      /*
767
        Sum RGB for this leaf for later derivation of the mean cube color.
768
      */
769
13.0M
      node_info->number_unique+=count;
770
13.0M
      node_info->total_red+=(double) count*p->red;
771
13.0M
      node_info->total_green+=(double) count*p->green;
772
13.0M
      node_info->total_blue+=(double) count*p->blue;
773
13.0M
      p+=count;
774
13.0M
    }
775
182k
    if (QuantumTick(y,image->rows))
776
57.5k
      if (!MagickMonitorFormatted(y,image->rows,exception,
777
57.5k
                                  ClassifyImageText,image->filename))
778
0
        {
779
0
          status=MagickFail;
780
0
          break;
781
0
        }
782
182k
  }
783
662
  return(status);
784
15.9k
}
785

786
/*
787
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
788
%                                                                             %
789
%                                                                             %
790
%                                                                             %
791
%   C l o n e Q u a n t i z e I n f o                                         %
792
%                                                                             %
793
%                                                                             %
794
%                                                                             %
795
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
796
%
797
%  CloneQuantizeInfo() makes a duplicate of the given quantize info structure,
798
%  or if quantize info is NULL, a new one.
799
%
800
%  The format of the CloneQuantizeInfo method is:
801
%
802
%      QuantizeInfo *CloneQuantizeInfo(const QuantizeInfo *quantize_info)
803
%
804
%  A description of each parameter follows:
805
%
806
%    o clone_info: Method CloneQuantizeInfo returns a duplicate of the given
807
%      quantize info, or if image info is NULL a new one.
808
%
809
%    o quantize_info: a structure of type info.
810
%
811
%
812
*/
813
MagickExport QuantizeInfo *CloneQuantizeInfo(const QuantizeInfo *quantize_info)
814
0
{
815
0
  QuantizeInfo
816
0
    *clone_info;
817
818
0
  clone_info=MagickAllocateMemory(QuantizeInfo *,sizeof(QuantizeInfo));
819
0
  if (clone_info == (QuantizeInfo *) NULL)
820
0
    MagickFatalError3(ResourceLimitFatalError,MemoryAllocationFailed,
821
0
      UnableToAllocateQuantizeInfo);
822
0
  GetQuantizeInfo(clone_info);
823
0
  if (quantize_info == (QuantizeInfo *) NULL)
824
0
    return(clone_info);
825
0
  clone_info->number_colors=quantize_info->number_colors;
826
0
  clone_info->tree_depth=quantize_info->tree_depth;
827
0
  clone_info->dither=quantize_info->dither;
828
0
  clone_info->colorspace=quantize_info->colorspace;
829
0
  clone_info->measure_error=quantize_info->measure_error;
830
0
  return(clone_info);
831
0
}
832

833
/*
834
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
835
%                                                                             %
836
%                                                                             %
837
%                                                                             %
838
+   C l o s e s t C o l o r                                                   %
839
%                                                                             %
840
%                                                                             %
841
%                                                                             %
842
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
843
%
844
%  ClosestColor() traverses the color cube tree at a particular node and
845
%  determines which colormap entry best represents the input color.
846
%
847
%  This is a recursive function.
848
%
849
%  The format of the ClosestColor method is:
850
%
851
%      void ClosestColor(Image *image,CubeInfo *cube_info,
852
%        const NodeInfo *node_info)
853
%
854
%  A description of each parameter follows.
855
%
856
%    o image: The image.
857
%
858
%    o cube_info: A pointer to the Cube structure.
859
%
860
%    o node_info: The address of a structure of type NodeInfo which points to a
861
%      node in the color cube tree that is to be pruned.
862
%
863
%
864
*/
865
static void ClosestColor(Image *image,CubeInfo *cube_info,
866
  const NodeInfo *node_info)
867
445M
{
868
445M
  register unsigned int
869
445M
    id;
870
871
  /*
872
    Traverse any children.
873
  */
874
4.00G
  for (id=0; id < MaxTreeDepth; id++)
875
3.56G
    if (node_info->child[id] != (NodeInfo *) NULL)
876
440M
      ClosestColor(image,cube_info,node_info->child[id]);
877
445M
  if (node_info->number_unique != 0)
878
124M
    {
879
124M
      double
880
124M
        distance;
881
882
124M
      DoublePixelPacket
883
124M
        pixel;
884
885
124M
      register PixelPacket
886
124M
        *color;
887
888
      /*
889
        Determine if this color is "closest".
890
      */
891
124M
      color=image->colormap+node_info->color_number;
892
124M
      pixel.red=color->red-cube_info->color.red;
893
124M
      distance=pixel.red*pixel.red;
894
124M
      if (distance < cube_info->distance)
895
69.0M
        {
896
69.0M
          pixel.green=color->green-cube_info->color.green;
897
69.0M
          distance+=pixel.green*pixel.green;
898
69.0M
          if (distance < cube_info->distance)
899
42.9M
            {
900
42.9M
              pixel.blue=color->blue-cube_info->color.blue;
901
42.9M
              distance+=pixel.blue*pixel.blue;
902
42.9M
              if (distance < cube_info->distance)
903
23.7M
                {
904
23.7M
                  cube_info->distance=distance;
905
23.7M
                  cube_info->color_number=node_info->color_number;
906
23.7M
                }
907
42.9M
            }
908
69.0M
        }
909
124M
    }
910
445M
}
911

912
/*
913
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
914
%                                                                             %
915
%                                                                             %
916
%                                                                             %
917
%   C o m p r e s s I m a g e C o l o r m a p                                 %
918
%                                                                             %
919
%                                                                             %
920
%                                                                             %
921
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
922
%
923
%  CompressImageColormap() compresses an image colormap by removing any
924
%  duplicate or unused color entries.
925
%
926
%  The format of the CompressImageColormap method is:
927
%
928
%      void CompressImageColormap(Image *image)
929
%
930
%  A description of each parameter follows:
931
%
932
%    o image: The image.
933
%
934
%
935
*/
936
MagickExport void CompressImageColormap(Image *image)
937
778
{
938
778
  QuantizeInfo
939
778
    quantize_info;
940
941
778
  assert(image != (Image *) NULL);
942
778
  assert(image->signature == MagickSignature);
943
778
  if (!IsPaletteImage(image,&image->exception))
944
78
    return;
945
700
  GetQuantizeInfo(&quantize_info);
946
700
  quantize_info.number_colors=image->colors;
947
700
  quantize_info.tree_depth=MaxTreeDepth;
948
700
  (void) QuantizeImage(&quantize_info,image);
949
700
}
950

951
/*
952
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
953
%                                                                             %
954
%                                                                             %
955
%                                                                             %
956
+   D e f i n e I m a g e C o l o r m a p                                     %
957
%                                                                             %
958
%                                                                             %
959
%                                                                             %
960
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
961
%
962
%  DefineImageColormap() traverses the color cube tree and notes each colormap
963
%  entry.  A colormap entry is any node in the color cube tree where the
964
%  of unique colors is not zero.
965
%
966
%  The format of the DefineImageColormap method is:
967
%
968
%      DefineImageColormap(Image *image,NodeInfo *node_info)
969
%
970
%  A description of each parameter follows.
971
%
972
%    o image: The image.
973
%
974
%    o node_info: The address of a structure of type NodeInfo which points to a
975
%      node in the color cube tree that is to be pruned.
976
%
977
%
978
*/
979
static void DefineImageColormap(Image *image,NodeInfo *node_info)
980
884k
{
981
884k
  register unsigned int
982
884k
    id;
983
984
  /*
985
    Traverse any children.
986
  */
987
7.96M
  for (id=0; id < MaxTreeDepth; id++)
988
7.07M
    if (node_info->child[id] != (NodeInfo *) NULL)
989
869k
      DefineImageColormap(image,node_info->child[id]);
990
884k
  if (node_info->number_unique != 0)
991
226k
    {
992
226k
      register double
993
226k
        number_unique;
994
995
      /*
996
        Colormap entry is defined by the mean color in this cube.
997
      */
998
226k
      number_unique=node_info->number_unique;
999
226k
      image->colormap[image->colors].red=(Quantum)
1000
226k
        (node_info->total_red/number_unique+0.5);
1001
226k
      image->colormap[image->colors].green=(Quantum)
1002
226k
        (node_info->total_green/number_unique+0.5);
1003
226k
      image->colormap[image->colors].blue=(Quantum)
1004
226k
        (node_info->total_blue/number_unique+0.5);
1005
226k
      node_info->color_number=image->colors++;
1006
226k
    }
1007
884k
}
1008

1009
/*
1010
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1011
%                                                                             %
1012
%                                                                             %
1013
%                                                                             %
1014
+   D e s t r o y C u b e I n f o                                             %
1015
%                                                                             %
1016
%                                                                             %
1017
%                                                                             %
1018
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1019
%
1020
%  DestroyCubeInfo() deallocates memory associated with an image.
1021
%
1022
%  The format of the DestroyCubeInfo method is:
1023
%
1024
%      DestroyCubeInfo(CubeInfo *cube_info)
1025
%
1026
%  A description of each parameter follows:
1027
%
1028
%    o cube_info: The address of a structure of type CubeInfo.
1029
%
1030
%
1031
*/
1032
static void DestroyCubeInfo(CubeInfo *cube_info)
1033
15.9k
{
1034
15.9k
  register Nodes
1035
15.9k
    *nodes;
1036
1037
  /*
1038
    Release color cube tree storage.
1039
  */
1040
15.9k
  do
1041
16.2k
  {
1042
16.2k
    nodes=cube_info->node_queue->next;
1043
16.2k
    MagickFreeMemory(cube_info->node_queue->nodes);
1044
16.2k
    MagickFreeMemory(cube_info->node_queue);
1045
16.2k
    cube_info->node_queue=nodes;
1046
16.2k
  } while (cube_info->node_queue != (Nodes *) NULL);
1047
15.9k
  if (cube_info->quantize_info->dither)
1048
15.3k
    MagickFreeMemory(cube_info->cache);
1049
15.9k
  MagickFreeMemory(cube_info);
1050
15.9k
}
1051

1052
/*
1053
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1054
%                                                                             %
1055
%                                                                             %
1056
%                                                                             %
1057
%   D e s t r o y Q u a n t i z e I n f o                                     %
1058
%                                                                             %
1059
%                                                                             %
1060
%                                                                             %
1061
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1062
%
1063
%  DestroyQuantizeInfo() deallocates memory associated with an QuantizeInfo
1064
%  structure.
1065
%
1066
%  The format of the DestroyQuantizeInfo method is:
1067
%
1068
%      DestroyQuantizeInfo(QuantizeInfo *quantize_info)
1069
%
1070
%  A description of each parameter follows:
1071
%
1072
%    o quantize_info: Specifies a pointer to an QuantizeInfo structure.
1073
%
1074
%
1075
*/
1076
MagickExport void DestroyQuantizeInfo(QuantizeInfo *quantize_info)
1077
578k
{
1078
578k
  assert(quantize_info != (QuantizeInfo *) NULL);
1079
578k
  assert(quantize_info->signature == MagickSignature);
1080
578k
  MagickFreeMemory(quantize_info);
1081
578k
}
1082

1083
/*
1084
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1085
%                                                                             %
1086
%                                                                             %
1087
%                                                                             %
1088
+   D i t h e r                                                               %
1089
%                                                                             %
1090
%                                                                             %
1091
%                                                                             %
1092
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1093
%
1094
%  Dither() distributes the difference between an original image and the
1095
%  corresponding color reduced algorithm to neighboring pixels along a Hilbert
1096
%  curve.
1097
%
1098
%  The format of the Dither method is:
1099
%
1100
%      unsigned int Dither(CubeInfo *cube_info,Image *image,
1101
%        const unsigned int direction)
1102
%
1103
%  A description of each parameter follows.
1104
%
1105
%    o cube_info: A pointer to the Cube structure.
1106
%
1107
%    o image: Specifies a pointer to an Image structure;  returned from
1108
%      ReadImage.
1109
%
1110
%    o direction:  This unsigned direction describes which direction
1111
%      to move to next to follow the Hilbert curve.
1112
%
1113
*/
1114
static MagickPassFail Dither(CubeInfo *cube_info,Image *image,
1115
  const unsigned int direction)
1116
208M
{
1117
208M
  DoublePixelPacket
1118
208M
    error;
1119
1120
208M
  IndexPacket
1121
208M
    index;
1122
1123
208M
  PixelPacket
1124
208M
    pixel;
1125
1126
208M
  register CubeInfo
1127
208M
    *p;
1128
1129
208M
  register IndexPacket
1130
208M
    *indexes;
1131
1132
208M
  register long
1133
208M
    i;
1134
1135
208M
  register PixelPacket
1136
208M
    *q;
1137
1138
208M
  p=cube_info;
1139
208M
  if ((p->x >= 0) && (p->x < (long) image->columns) &&
1140
104M
      (p->y >= 0) && (p->y < (long) image->rows))
1141
41.4M
    {
1142
      /*
1143
        Distribute error.
1144
      */
1145
41.4M
      q=GetImagePixels(image,p->x,p->y,1,1);
1146
41.4M
      if (q == (PixelPacket *) NULL)
1147
0
        return(MagickFail);
1148
41.4M
      indexes=AccessMutableIndexes(image);
1149
41.4M
      error.red=q->red;
1150
41.4M
      error.green=q->green;
1151
41.4M
      error.blue=q->blue;
1152
704M
      for (i=0; i < ExceptionQueueLength; i++)
1153
662M
      {
1154
662M
        error.red+=p->error[i].red*p->weights[i];
1155
662M
        error.green+=p->error[i].green*p->weights[i];
1156
662M
        error.blue+=p->error[i].blue*p->weights[i];
1157
662M
      }
1158
1159
41.4M
      pixel.red=RoundDoubleToQuantum(error.red);
1160
41.4M
      pixel.green=RoundDoubleToQuantum(error.green);
1161
41.4M
      pixel.blue=RoundDoubleToQuantum(error.blue);
1162
1163
41.4M
      i=(pixel.blue >> CacheShift) << 12 | (pixel.green >> CacheShift) << 6 |
1164
41.4M
        (pixel.red >> CacheShift);
1165
41.4M
      if (p->cache[i] < 0)
1166
2.38M
        {
1167
2.38M
          register NodeInfo
1168
2.38M
            *node_info;
1169
1170
2.38M
          register unsigned int
1171
2.38M
            id;
1172
1173
          /*
1174
            Identify the deepest node containing the pixel's color.
1175
          */
1176
2.38M
          node_info=p->root;
1177
10.0M
          for (index=MaxTreeDepth-1; (long) index > 0; index--)
1178
9.98M
          {
1179
9.98M
            id=ColorToNodeId(pixel.red,pixel.green,pixel.blue,index);
1180
9.98M
            if (node_info->child[id] == (NodeInfo *) NULL)
1181
2.35M
              break;
1182
7.62M
            node_info=node_info->child[id];
1183
7.62M
          }
1184
          /*
1185
            Find closest color among siblings and their children.
1186
          */
1187
2.38M
          p->color.red=pixel.red;
1188
2.38M
          p->color.green=pixel.green;
1189
2.38M
          p->color.blue=pixel.blue;
1190
2.38M
          p->distance=3.0*(MaxRGBDouble+1.0)*(MaxRGBDouble+1.0);
1191
2.38M
          ClosestColor(image,p,node_info->parent);
1192
2.38M
          p->cache[i]=(long) p->color_number;
1193
2.38M
        }
1194
      /*
1195
        Assign pixel to closest colormap entry.
1196
      */
1197
41.4M
      index=(IndexPacket) p->cache[i];
1198
41.4M
      if (image->storage_class == PseudoClass)
1199
41.4M
        *indexes=index;
1200
41.4M
      if (!cube_info->quantize_info->measure_error)
1201
41.4M
        {
1202
41.4M
          q->red=image->colormap[index].red;
1203
41.4M
          q->green=image->colormap[index].green;
1204
41.4M
          q->blue=image->colormap[index].blue;
1205
41.4M
        }
1206
41.4M
      if (!SyncImagePixels(image))
1207
0
        return(MagickFail);
1208
      /*
1209
        Propagate the error as the last entry of the error queue.
1210
      */
1211
662M
      for (i=0; i < (ExceptionQueueLength-1); i++)
1212
621M
        p->error[i]=p->error[i+1];
1213
41.4M
      p->error[i].red=pixel.red-(double) image->colormap[index].red;
1214
41.4M
      p->error[i].green=pixel.green-(double) image->colormap[index].green;
1215
41.4M
      p->error[i].blue=pixel.blue-(double) image->colormap[index].blue;
1216
41.4M
    }
1217
208M
  switch (direction)
1218
208M
  {
1219
51.8M
    case WestGravity: p->x--; break;
1220
52.1M
    case EastGravity: p->x++; break;
1221
52.0M
    case NorthGravity: p->y--; break;
1222
52.0M
    case SouthGravity: p->y++; break;
1223
208M
  }
1224
208M
  return(MagickPass);
1225
208M
}
1226

1227
/*
1228
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1229
%                                                                             %
1230
%                                                                             %
1231
%                                                                             %
1232
+   D i t h e r I m a g e                                                     %
1233
%                                                                             %
1234
%                                                                             %
1235
%                                                                             %
1236
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1237
%
1238
%  DitherImage() distributes the difference between an original image and the
1239
%  corresponding color reduced algorithm to neighboring pixels along a Hilbert
1240
%  curve.  DitherImage returns True if the image is dithered otherwise False.
1241
%
1242
%  This algorithm is strongly based on a similar algorithm by Thiadmer
1243
%  Riemersma.
1244
%
1245
%  The format of the DitherImage method is:
1246
%
1247
%      unsigned int DitherImage(CubeInfo *cube_info,Image *image)
1248
%
1249
%  A description of each parameter follows.
1250
%
1251
%    o cube_info: A pointer to the Cube structure.
1252
%
1253
%    o image: Specifies a pointer to an Image structure;  returned from
1254
%      ReadImage.
1255
%
1256
%
1257
*/
1258
static MagickPassFail DitherImage(CubeInfo *cube_info,Image *image)
1259
15.2k
{
1260
15.2k
  register unsigned long
1261
15.2k
    i;
1262
1263
15.2k
  unsigned long
1264
15.2k
    depth;
1265
1266
  /*
1267
    Initialize error queue.
1268
  */
1269
260k
  for (i=0; i < ExceptionQueueLength; i++)
1270
244k
  {
1271
244k
    cube_info->error[i].red=0.0;
1272
244k
    cube_info->error[i].green=0.0;
1273
244k
    cube_info->error[i].blue=0.0;
1274
244k
  }
1275
  /*
1276
    Distribute quantization error along a Hilbert curve.
1277
  */
1278
15.2k
  cube_info->x=0;
1279
15.2k
  cube_info->y=0;
1280
15.2k
  i=image->columns > image->rows ? image->columns : image->rows;
1281
40.9k
  for (depth=1; i != 0; depth++)
1282
25.6k
    i>>=1;
1283
15.2k
  HilbertCurve(cube_info,image,depth-1,NorthGravity);
1284
15.2k
  (void) Dither(cube_info,image,ForgetGravity);
1285
15.2k
  return(MagickPass);
1286
15.2k
}
1287

1288
/*
1289
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1290
%                                                                             %
1291
%                                                                             %
1292
%                                                                             %
1293
+   G e t C u b e I n f o                                                     %
1294
%                                                                             %
1295
%                                                                             %
1296
%                                                                             %
1297
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1298
%
1299
%  GetCubeInfo() initialize the Cube data structure.
1300
%
1301
%  The format of the GetCubeInfo method is:
1302
%
1303
%      CubeInfo GetCubeInfo(const QuantizeInfo *quantize_info,
1304
%        unsigned int depth)
1305
%
1306
%  A description of each parameter follows.
1307
%
1308
%    o cube_info: A pointer to the Cube structure.
1309
%
1310
%    o quantize_info: Specifies a pointer to an QuantizeInfo structure.
1311
%
1312
%    o depth: Normally, this integer value is zero or one.  A zero or
1313
%      one tells Quantize to choose a optimal tree depth of Log4(number_colors).
1314
%      A tree of this depth generally allows the best representation of the
1315
%      reference image with the least amount of memory and the fastest
1316
%      computational speed.  In some cases, such as an image with low color
1317
%      dispersion (a few number of colors), a value other than
1318
%      Log4(number_colors) is required.  To expand the color tree completely,
1319
%      use a value of 8.
1320
%
1321
%
1322
*/
1323
static CubeInfo *GetCubeInfo(const QuantizeInfo *quantize_info,
1324
  unsigned long depth)
1325
15.9k
{
1326
15.9k
  CubeInfo
1327
15.9k
    *cube_info;
1328
1329
15.9k
  double
1330
15.9k
    sum,
1331
15.9k
    weight;
1332
1333
15.9k
  register long
1334
15.9k
    i;
1335
1336
  /*
1337
    Initialize tree to describe color cube_info.
1338
  */
1339
15.9k
  cube_info=MagickAllocateMemory(CubeInfo *,sizeof(CubeInfo));
1340
15.9k
  if (cube_info == (CubeInfo *) NULL)
1341
0
    return((CubeInfo *) NULL);
1342
15.9k
  (void) memset(cube_info,0,sizeof(CubeInfo));
1343
15.9k
  if (depth > MaxTreeDepth)
1344
0
    depth=MaxTreeDepth;
1345
15.9k
  if (depth < 2)
1346
0
    depth=2;
1347
15.9k
  cube_info->depth=depth;
1348
  /*
1349
    Initialize root node.
1350
  */
1351
15.9k
  cube_info->root=GetNodeInfo(cube_info,0,0,(NodeInfo *) NULL);
1352
15.9k
  if (cube_info->root == (NodeInfo *) NULL)
1353
0
    return((CubeInfo *) NULL);
1354
15.9k
  cube_info->root->parent=cube_info->root;
1355
15.9k
  cube_info->quantize_info=quantize_info;
1356
15.9k
  if (!cube_info->quantize_info->dither)
1357
628
    return(cube_info);
1358
  /*
1359
    Initialize dither resources.
1360
  */
1361
15.3k
  cube_info->cache=MagickAllocateMemory(long *,(1 << 18)*sizeof(long));
1362
15.3k
  if (cube_info->cache == (long *) NULL)
1363
0
    return((CubeInfo *) NULL);
1364
  /*
1365
    Initialize color cache.
1366
  */
1367
4.01G
  for (i=0; i < (1 << 18); i++)
1368
4.01G
    cube_info->cache[i]=(-1);
1369
  /*
1370
    Distribute weights along a curve of exponential decay.
1371
  */
1372
15.3k
  weight=1.0;
1373
260k
  for (i=0; i < ExceptionQueueLength; i++)
1374
245k
  {
1375
245k
    cube_info->weights[ExceptionQueueLength-i-1]=1.0/weight;
1376
245k
    weight*=exp(log((MaxRGBDouble+1.0))/(ExceptionQueueLength-1.0));
1377
245k
  }
1378
  /*
1379
    Normalize the weighting factors.
1380
  */
1381
15.3k
  weight=0.0;
1382
260k
  for (i=0; i < ExceptionQueueLength; i++)
1383
245k
    weight+=cube_info->weights[i];
1384
15.3k
  sum=0.0;
1385
260k
  for (i=0; i < ExceptionQueueLength; i++)
1386
245k
  {
1387
245k
    cube_info->weights[i]/=weight;
1388
245k
    sum+=cube_info->weights[i];
1389
245k
  }
1390
15.3k
  cube_info->weights[0]+=1.0-sum;
1391
15.3k
  return(cube_info);
1392
15.3k
}
1393

1394
/*
1395
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1396
%                                                                             %
1397
%                                                                             %
1398
%                                                                             %
1399
+   G e t N o d e I n f o                                                     %
1400
%                                                                             %
1401
%                                                                             %
1402
%                                                                             %
1403
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1404
%
1405
%  GetNodeInfo() allocates memory for a new node in the color cube tree and
1406
%  presets all fields to zero.
1407
%
1408
%  The format of the GetNodeInfo method is:
1409
%
1410
%      NodeInfo *GetNodeInfo(CubeInfo *cube_info,const unsigned int id,
1411
%        const unsigned int level,NodeInfo *parent)
1412
%
1413
%  A description of each parameter follows.
1414
%
1415
%    o node: The GetNodeInfo method returns this integer address.
1416
%
1417
%    o id: Specifies the child number of the node.
1418
%
1419
%    o level: Specifies the level in the storage_class the node resides.
1420
%
1421
%
1422
*/
1423
static NodeInfo *GetNodeInfo(CubeInfo *cube_info,const unsigned int id,
1424
  const unsigned int level,NodeInfo *parent)
1425
1.66M
{
1426
1.66M
  NodeInfo
1427
1.66M
    *node_info;
1428
1429
1.66M
  if (cube_info->free_nodes == 0)
1430
16.2k
    {
1431
16.2k
      Nodes
1432
16.2k
        *nodes;
1433
1434
      /*
1435
        Allocate a new nodes of nodes.
1436
      */
1437
16.2k
      nodes=MagickAllocateMemory(Nodes *,sizeof(Nodes));
1438
16.2k
      if (nodes == (Nodes *) NULL)
1439
0
        return((NodeInfo *) NULL);
1440
16.2k
      nodes->nodes=MagickAllocateMemory(NodeInfo *,(NodesInAList*sizeof(NodeInfo)));
1441
16.2k
      if (nodes->nodes == (NodeInfo *) NULL)
1442
0
        return((NodeInfo *) NULL);
1443
16.2k
      nodes->next=cube_info->node_queue;
1444
16.2k
      cube_info->node_queue=nodes;
1445
16.2k
      cube_info->next_node=nodes->nodes;
1446
16.2k
      cube_info->free_nodes=NodesInAList;
1447
16.2k
    }
1448
1.66M
  cube_info->nodes++;
1449
1.66M
  cube_info->free_nodes--;
1450
1.66M
  node_info=cube_info->next_node++;
1451
1.66M
  (void) memset(node_info,0,sizeof(NodeInfo));
1452
1.66M
  node_info->parent=parent;
1453
1.66M
  node_info->id=id;
1454
1.66M
  node_info->level=level;
1455
1.66M
  return(node_info);
1456
1.66M
}
1457

1458
/*
1459
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1460
%                                                                             %
1461
%                                                                             %
1462
%                                                                             %
1463
%  G e t I m a g e Q u a n t i z e E r r o r                                  %
1464
%                                                                             %
1465
%                                                                             %
1466
%                                                                             %
1467
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1468
%
1469
%  GetImageQuantizeError() measures the difference between the original
1470
%  and quantized images.  This difference is the total quantization error.
1471
%  The error is computed by summing over all pixels in an image the distance
1472
%  squared in RGB space between each reference pixel value and its quantized
1473
%  value.  These values are computed:
1474
%
1475
%    o mean_error_per_pixel:  This value is the mean error for any single
1476
%      pixel in the image.
1477
%
1478
%    o normalized_mean_square_error:  This value is the normalized mean
1479
%      quantization error for any single pixel in the image.  This distance
1480
%      measure is normalized to a range between 0 and 1.  It is independent
1481
%      of the range of red, green, and blue values in the image.
1482
%
1483
%    o normalized_maximum_square_error:  This value is the normalized
1484
%      maximum quantization error for any single pixel in the image.  This
1485
%      distance measure is normalized to a range between 0 and 1.  It is
1486
%      independent of the range of red, green, and blue values in your image.
1487
%
1488
%
1489
%  The format of the GetImageQuantizeError method is:
1490
%
1491
%      unsigned int GetImageQuantizeError(Image *image)
1492
%
1493
%  A description of each parameter follows.
1494
%
1495
%    o image: Specifies a pointer to an Image structure;  returned from
1496
%      ReadImage.
1497
%
1498
%
1499
*/
1500
MagickExport MagickPassFail GetImageQuantizeError(Image *image)
1501
0
{
1502
0
  double
1503
0
    distance,
1504
0
    maximum_error_per_pixel,
1505
0
    normalize;
1506
1507
0
  DoublePixelPacket
1508
0
    pixel;
1509
1510
0
  IndexPacket
1511
0
    index;
1512
1513
0
  long
1514
0
    y;
1515
1516
0
  ErrorSumType
1517
0
    total_error;
1518
1519
0
  register const PixelPacket
1520
0
    *p;
1521
1522
0
  register const IndexPacket
1523
0
    *indexes;
1524
1525
0
  register long
1526
0
    x;
1527
1528
0
  MagickPassFail
1529
0
    status=MagickPass;
1530
1531
  /*
1532
    Initialize measurement.
1533
  */
1534
0
  assert(image != (Image *) NULL);
1535
0
  assert(image->signature == MagickSignature);
1536
0
  image->total_colors=GetNumberColors(image,(FILE *) NULL,&image->exception);
1537
0
  (void) memset(&image->error,0,sizeof(ErrorInfo));
1538
0
  if (image->storage_class == DirectClass)
1539
0
    return(MagickFail);
1540
  /*
1541
    For each pixel, collect error statistics.
1542
  */
1543
0
  maximum_error_per_pixel=0;
1544
0
  total_error=0;
1545
0
  for (y=0; y < (long) image->rows; y++)
1546
0
  {
1547
0
    p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
1548
0
    if (p == (const PixelPacket *) NULL)
1549
0
      {
1550
0
        status=MagickFail;
1551
0
        break;
1552
0
      }
1553
0
    indexes=AccessImmutableIndexes(image);
1554
0
    for (x=0; x < (long) image->columns; x++)
1555
0
    {
1556
0
      index=indexes[x];
1557
0
      pixel.red=p->red-(double) image->colormap[index].red;
1558
0
      pixel.green=p->green-(double) image->colormap[index].green;
1559
0
      pixel.blue=p->blue-(double) image->colormap[index].blue;
1560
0
      distance=pixel.red*pixel.red+pixel.green*pixel.green+
1561
0
        pixel.blue*pixel.blue;
1562
0
      total_error+=distance;
1563
0
      if (distance > maximum_error_per_pixel)
1564
0
        maximum_error_per_pixel=distance;
1565
0
      p++;
1566
0
    }
1567
0
  }
1568
  /*
1569
    Compute final error statistics.
1570
  */
1571
0
  normalize=3.0*(MaxRGBDouble+1.0)*(MaxRGBDouble+1.0);
1572
0
  image->error.mean_error_per_pixel=total_error/image->columns/image->rows;
1573
0
  image->error.normalized_mean_error=
1574
0
    image->error.mean_error_per_pixel/normalize;
1575
0
  image->error.normalized_maximum_error=maximum_error_per_pixel/normalize;
1576
0
  return(status);
1577
0
}
1578

1579
/*
1580
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1581
%                                                                             %
1582
%                                                                             %
1583
%                                                                             %
1584
%   G e t Q u a n t i z e I n f o                                             %
1585
%                                                                             %
1586
%                                                                             %
1587
%                                                                             %
1588
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1589
%
1590
%  GetQuantizeInfo() initializes the QuantizeInfo structure.
1591
%
1592
%  The format of the GetQuantizeInfo method is:
1593
%
1594
%      GetQuantizeInfo(QuantizeInfo *quantize_info)
1595
%
1596
%  A description of each parameter follows:
1597
%
1598
%    o quantize_info: Specifies a pointer to a QuantizeInfo structure.
1599
%
1600
%
1601
*/
1602
MagickExport void GetQuantizeInfo(QuantizeInfo *quantize_info)
1603
598k
{
1604
598k
  assert(quantize_info != (QuantizeInfo *) NULL);
1605
598k
  (void) memset(quantize_info,0,sizeof(QuantizeInfo));
1606
598k
  quantize_info->number_colors=256;
1607
598k
  quantize_info->dither=True;
1608
598k
  quantize_info->colorspace=RGBColorspace;
1609
598k
  quantize_info->signature=MagickSignature;
1610
598k
}
1611

1612
/*
1613
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1614
%                                                                             %
1615
%                                                                             %
1616
%                                                                             %
1617
%   G r a y s c a l e P s e u d o C l a s s I m a g e                         %
1618
%                                                                             %
1619
%                                                                             %
1620
%                                                                             %
1621
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1622
%
1623
%  GrayscalePseudoClassImage converts an image to a PseudoClass
1624
%  grayscale representation with an (optionally) compressed and sorted
1625
%  colormap. Colormap is ordered by increasing intensity.
1626
%
1627
%  The format of the GrayscalePseudoClassImage method is:
1628
%
1629
%      void GrayscalePseudoClassImage(Image *image)
1630
%
1631
%  A description of each parameter follows:
1632
%
1633
%    o image: The image.
1634
%
1635
%    o optimize_colormap: If true, produce an optimimal (compact) colormap.
1636
%
1637
*/
1638
1639
#if defined(__cplusplus) || defined(c_plusplus)
1640
extern "C" {
1641
#endif
1642
1643
static int IntensityCompare(const void *x,const void *y)
1644
14.8M
{
1645
14.8M
  long
1646
14.8M
    intensity;
1647
1648
14.8M
  PixelPacket
1649
14.8M
    *color_1,
1650
14.8M
    *color_2;
1651
1652
14.8M
  color_1=(PixelPacket *) x;
1653
14.8M
  color_2=(PixelPacket *) y;
1654
14.8M
  intensity=PixelIntensityToQuantum(color_1)-
1655
14.8M
    (long) PixelIntensityToQuantum(color_2);
1656
14.8M
  return(intensity);
1657
14.8M
}
1658
1659
#if defined(__cplusplus) || defined(c_plusplus)
1660
}
1661
#endif
1662
1663
MagickExport void GrayscalePseudoClassImage(Image *image,
1664
  unsigned int optimize_colormap)
1665
4.00k
{
1666
4.00k
  long
1667
4.00k
    y;
1668
1669
4.00k
  register long
1670
4.00k
    x;
1671
1672
4.00k
  register IndexPacket
1673
4.00k
    *indexes;
1674
1675
4.00k
  register const PixelPacket
1676
4.00k
    *q;
1677
1678
4.00k
  register unsigned int
1679
4.00k
    i;
1680
1681
4.00k
  int
1682
4.00k
    *colormap_index=(int *) NULL;
1683
1684
4.00k
  assert(image != (Image *) NULL);
1685
4.00k
  assert(image->signature == MagickSignature);
1686
1687
4.00k
  if (!image->is_grayscale)
1688
0
    (void) TransformColorspace(image,GRAYColorspace);
1689
1690
4.00k
  if (image->storage_class != PseudoClass)
1691
3.36k
    {
1692
      /*
1693
        Allocate maximum sized grayscale image colormap
1694
      */
1695
3.36k
      if (!AllocateImageColormap(image,MaxColormapSize))
1696
0
        {
1697
0
          ThrowException3(&image->exception,ResourceLimitError,
1698
0
            MemoryAllocationFailed,UnableToSortImageColormap);
1699
0
          return;
1700
0
        }
1701
1702
3.36k
      if (optimize_colormap)
1703
3.36k
        {
1704
          /*
1705
            Use minimal colormap method.
1706
          */
1707
1708
          /*
1709
            Allocate memory for colormap index
1710
          */
1711
3.36k
          colormap_index=MagickAllocateMemory(int *,MaxColormapSize*sizeof(int));
1712
3.36k
          if (colormap_index == (int *) NULL)
1713
0
            {
1714
0
              ThrowException3(&image->exception,ResourceLimitError,
1715
0
                MemoryAllocationFailed,UnableToSortImageColormap);
1716
0
              return;
1717
0
            }
1718
1719
          /*
1720
            Initial colormap index value is -1 so we can tell if it
1721
            is initialized.
1722
          */
1723
220M
          for (i=0; i < MaxColormapSize; i++)
1724
220M
            colormap_index[i]=-1;
1725
1726
3.36k
          image->colors=0;
1727
36.5k
          for (y=0; y < (long) image->rows; y++)
1728
33.1k
            {
1729
33.1k
              q=GetImagePixels(image,0,y,image->columns,1);
1730
33.1k
              if (q == (PixelPacket *) NULL)
1731
0
                break;
1732
33.1k
              indexes=AccessMutableIndexes(image);
1733
10.2M
              for (x=(long) image->columns; x > 0; x--)
1734
10.1M
                {
1735
10.1M
                  register int
1736
10.1M
                    intensity;
1737
1738
                  /*
1739
                    If index is new, create index to colormap
1740
                  */
1741
10.1M
                  intensity=ScaleQuantumToMap(q->red);
1742
10.1M
                  if (colormap_index[intensity] < 0)
1743
110k
                    {
1744
110k
                      colormap_index[intensity]=image->colors;
1745
110k
                      image->colormap[image->colors]=*q;
1746
110k
                      image->colors++;
1747
110k
                    }
1748
10.1M
                  *indexes++=colormap_index[intensity];
1749
10.1M
                  q++;
1750
10.1M
                }
1751
33.1k
              if (!SyncImagePixels(image))
1752
0
                {
1753
0
                  MagickFreeMemory(colormap_index);
1754
0
                  return;
1755
0
                }
1756
33.1k
            }
1757
3.36k
        }
1758
0
      else
1759
0
        {
1760
          /*
1761
            Use fast-cut linear colormap method.
1762
          */
1763
0
          for (y=0; y < (long) image->rows; y++)
1764
0
            {
1765
0
              q=GetImagePixels(image,0,y,image->columns,1);
1766
0
              if (q == (PixelPacket *) NULL)
1767
0
                break;
1768
0
              indexes=AccessMutableIndexes(image);
1769
0
              for (x=(long) image->columns; x > 0; x--)
1770
0
                {
1771
0
                  *indexes=ScaleQuantumToIndex(q->red);
1772
0
                  q++;
1773
0
                  indexes++;
1774
0
                }
1775
0
              if (!SyncImagePixels(image))
1776
0
                break;
1777
0
           }
1778
0
          image->is_grayscale=True;
1779
0
          return;
1780
0
        }
1781
3.36k
    }
1782
1783
4.00k
  if (optimize_colormap)
1784
4.00k
    {
1785
      /*
1786
        Sort and compact the colormap
1787
      */
1788
1789
      /*
1790
        Allocate memory for colormap index
1791
      */
1792
4.00k
      if (colormap_index == (int *) NULL)
1793
639
        {
1794
639
          colormap_index=MagickAllocateArray(int *,MaxColormapSize,sizeof(int));
1795
639
          if (colormap_index == (int *) NULL)
1796
0
            {
1797
0
              ThrowException3(&image->exception,ResourceLimitError,
1798
0
                MemoryAllocationFailed,UnableToSortImageColormap);
1799
0
              return;
1800
0
            }
1801
639
        }
1802
1803
      /*
1804
        Assign index values to colormap entries.
1805
      */
1806
1.83M
      for (i=0; i < image->colors; i++)
1807
1.83M
        image->colormap[i].opacity=(unsigned short) i;
1808
      /*
1809
        Sort image colormap by increasing intensity.
1810
      */
1811
4.00k
      qsort((void *) image->colormap,image->colors,sizeof(PixelPacket),
1812
4.00k
            IntensityCompare);
1813
      /*
1814
        Create mapping between original indexes and reduced/sorted
1815
        colormap.
1816
      */
1817
4.00k
      {
1818
4.00k
        PixelPacket
1819
4.00k
          *new_colormap;
1820
1821
4.00k
        int
1822
4.00k
          j;
1823
1824
4.00k
        new_colormap=MagickAllocateMemory(PixelPacket *,image->colors*sizeof(PixelPacket));
1825
4.00k
        if (new_colormap == (PixelPacket *) NULL)
1826
78
          {
1827
78
            MagickFreeMemory(colormap_index);
1828
78
            ThrowException3(&image->exception,ResourceLimitError,
1829
78
              MemoryAllocationFailed,UnableToSortImageColormap);
1830
78
            return;
1831
78
          }
1832
1833
3.92k
        j=0;
1834
3.92k
        new_colormap[j]=image->colormap[0];
1835
1.83M
        for (i=0; i < image->colors; i++)
1836
1.83M
          {
1837
1.83M
            if (NotColorMatch(&new_colormap[j],&image->colormap[i]))
1838
1.82M
              {
1839
1.82M
                j++;
1840
1.82M
                new_colormap[j]=image->colormap[i];
1841
1.82M
              }
1842
1843
1.83M
            colormap_index[image->colormap[i].opacity]=j;
1844
1.83M
          }
1845
3.92k
        image->colors=j+1;
1846
3.92k
        MagickFreeMemory(image->colormap);
1847
3.92k
        image->colormap=new_colormap;
1848
3.92k
      }
1849
1850
      /*
1851
        Reassign image colormap indexes
1852
      */
1853
54.0k
      for (y=0; y < (long) image->rows; y++)
1854
50.1k
        {
1855
50.1k
          q=GetImagePixels(image,0,y,image->columns,1);
1856
50.1k
          if (q == (PixelPacket *) NULL)
1857
22
            break;
1858
50.0k
          indexes=AccessMutableIndexes(image);
1859
10.4M
          for (x=(long) image->columns; x > 0; x--)
1860
10.4M
            {
1861
10.4M
              *indexes=colormap_index[*indexes];
1862
10.4M
              indexes++;
1863
10.4M
            }
1864
50.0k
          if (!SyncImagePixels(image))
1865
0
            break;
1866
50.0k
        }
1867
3.92k
      MagickFreeMemory(colormap_index);
1868
3.92k
    }
1869
3.92k
  image->is_monochrome=IsMonochromeImage(image,&image->exception);
1870
3.92k
  image->is_grayscale=True;
1871
3.92k
}
1872

1873
/*
1874
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1875
%                                                                             %
1876
%                                                                             %
1877
%                                                                             %
1878
+   H i l b e r t C u r v e                                                   %
1879
%                                                                             %
1880
%                                                                             %
1881
%                                                                             %
1882
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1883
%
1884
%  HilbertCurve() s a space filling curve that visits every point in a square
1885
%  grid with any power of 2.  Hilbert is useful in dithering due to the
1886
%  coherence between neighboring pixels.  Here, the quantization error is
1887
%  distributed along the Hilbert curve.
1888
%
1889
%  This is a recursive function.
1890
%
1891
%  The format of the HilbertCurve method is:
1892
%
1893
%      void HilbertCurve(CubeInfo *cube_info,Image *image,
1894
%        const unsigned long level,const unsigned int direction)
1895
%
1896
%  A description of each parameter follows.
1897
%
1898
%    o cube_info: A pointer to the Cube structure.
1899
%
1900
%    o image: Specifies a pointer to an Image structure;  returned from
1901
%      ReadImage.
1902
%
1903
%    o direction:  This unsigned direction describes which direction
1904
%      to move to next to follow the Hilbert curve.
1905
%
1906
%
1907
*/
1908
static void HilbertCurve(CubeInfo *cube_info,Image *image,
1909
  const unsigned long level,const unsigned int direction)
1910
69.3M
{
1911
69.3M
  if (level == 1)
1912
52.0M
    {
1913
52.0M
      switch (direction)
1914
52.0M
      {
1915
13.0M
        case WestGravity:
1916
13.0M
        {
1917
13.0M
          (void) Dither(cube_info,image,EastGravity);
1918
13.0M
          (void) Dither(cube_info,image,SouthGravity);
1919
13.0M
          (void) Dither(cube_info,image,WestGravity);
1920
13.0M
          break;
1921
0
        }
1922
13.0M
        case EastGravity:
1923
13.0M
        {
1924
13.0M
          (void) Dither(cube_info,image,WestGravity);
1925
13.0M
          (void) Dither(cube_info,image,NorthGravity);
1926
13.0M
          (void) Dither(cube_info,image,EastGravity);
1927
13.0M
          break;
1928
0
        }
1929
13.1M
        case NorthGravity:
1930
13.1M
        {
1931
13.1M
          (void) Dither(cube_info,image,SouthGravity);
1932
13.1M
          (void) Dither(cube_info,image,EastGravity);
1933
13.1M
          (void) Dither(cube_info,image,NorthGravity);
1934
13.1M
          break;
1935
0
        }
1936
12.9M
        case SouthGravity:
1937
12.9M
        {
1938
12.9M
          (void) Dither(cube_info,image,NorthGravity);
1939
12.9M
          (void) Dither(cube_info,image,WestGravity);
1940
12.9M
          (void) Dither(cube_info,image,SouthGravity);
1941
12.9M
          break;
1942
0
        }
1943
0
        default:
1944
0
          break;
1945
52.0M
      }
1946
52.0M
      return;
1947
52.0M
    }
1948
17.3M
  switch (direction)
1949
17.3M
  {
1950
4.33M
    case WestGravity:
1951
4.33M
    {
1952
4.33M
      HilbertCurve(cube_info,image,level-1,NorthGravity);
1953
4.33M
      (void) Dither(cube_info,image,EastGravity);
1954
4.33M
      HilbertCurve(cube_info,image,level-1,WestGravity);
1955
4.33M
      (void) Dither(cube_info,image,SouthGravity);
1956
4.33M
      HilbertCurve(cube_info,image,level-1,WestGravity);
1957
4.33M
      (void) Dither(cube_info,image,WestGravity);
1958
4.33M
      HilbertCurve(cube_info,image,level-1,SouthGravity);
1959
4.33M
      break;
1960
0
    }
1961
4.33M
    case EastGravity:
1962
4.33M
    {
1963
4.33M
      HilbertCurve(cube_info,image,level-1,SouthGravity);
1964
4.33M
      (void) Dither(cube_info,image,WestGravity);
1965
4.33M
      HilbertCurve(cube_info,image,level-1,EastGravity);
1966
4.33M
      (void) Dither(cube_info,image,NorthGravity);
1967
4.33M
      HilbertCurve(cube_info,image,level-1,EastGravity);
1968
4.33M
      (void) Dither(cube_info,image,EastGravity);
1969
4.33M
      HilbertCurve(cube_info,image,level-1,NorthGravity);
1970
4.33M
      break;
1971
0
    }
1972
4.42M
    case NorthGravity:
1973
4.42M
    {
1974
4.42M
      HilbertCurve(cube_info,image,level-1,WestGravity);
1975
4.42M
      (void) Dither(cube_info,image,SouthGravity);
1976
4.42M
      HilbertCurve(cube_info,image,level-1,NorthGravity);
1977
4.42M
      (void) Dither(cube_info,image,EastGravity);
1978
4.42M
      HilbertCurve(cube_info,image,level-1,NorthGravity);
1979
4.42M
      (void) Dither(cube_info,image,NorthGravity);
1980
4.42M
      HilbertCurve(cube_info,image,level-1,EastGravity);
1981
4.42M
      break;
1982
0
    }
1983
4.24M
    case SouthGravity:
1984
4.24M
    {
1985
4.24M
      HilbertCurve(cube_info,image,level-1,EastGravity);
1986
4.24M
      (void) Dither(cube_info,image,NorthGravity);
1987
4.24M
      HilbertCurve(cube_info,image,level-1,SouthGravity);
1988
4.24M
      (void) Dither(cube_info,image,WestGravity);
1989
4.24M
      HilbertCurve(cube_info,image,level-1,SouthGravity);
1990
4.24M
      (void) Dither(cube_info,image,SouthGravity);
1991
4.24M
      HilbertCurve(cube_info,image,level-1,WestGravity);
1992
4.24M
      break;
1993
0
    }
1994
0
    default:
1995
0
      break;
1996
17.3M
  }
1997
17.3M
}
1998

1999
/*
2000
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2001
%                                                                             %
2002
%                                                                             %
2003
%                                                                             %
2004
%   M a p I m a g e                                                           %
2005
%                                                                             %
2006
%                                                                             %
2007
%                                                                             %
2008
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2009
%
2010
%  MapImage() replaces the colors of an image with the closest color from a
2011
%  reference image.
2012
%
2013
%  The format of the MapImage method is:
2014
%
2015
%      unsigned int MapImage(Image *image,const Image *map_image,
2016
%        const unsigned int dither)
2017
%
2018
%  A description of each parameter follows:
2019
%
2020
%    o image: Specifies a pointer to an Image structure.
2021
%
2022
%    o map_image: Specifies a pointer to an Image structure.  Reduce
2023
%      image to a set of colors represented by this image.
2024
%
2025
%    o dither: Set this integer value to something other than zero to
2026
%      dither the quantized image.
2027
%
2028
%
2029
*/
2030
MagickExport MagickPassFail MapImage(Image *image,const Image *map_image,
2031
  const unsigned int dither)
2032
1.31k
{
2033
1.31k
  CubeInfo
2034
1.31k
    *cube_info;
2035
2036
1.31k
  QuantizeInfo
2037
1.31k
    quantize_info;
2038
2039
1.31k
  MagickPassFail
2040
1.31k
    status=MagickPass;
2041
2042
  /*
2043
    Initialize color cube.
2044
  */
2045
1.31k
  assert(image != (Image *) NULL);
2046
1.31k
  assert(image->signature == MagickSignature);
2047
1.31k
  assert(map_image != (Image *) NULL);
2048
1.31k
  assert(map_image->signature == MagickSignature);
2049
1.31k
  GetQuantizeInfo(&quantize_info);
2050
1.31k
  quantize_info.dither=dither;
2051
1.31k
  quantize_info.colorspace=
2052
1.31k
    image->matte ? TransparentColorspace : RGBColorspace;
2053
1.31k
  cube_info=GetCubeInfo(&quantize_info,MaxTreeDepth);
2054
1.31k
  if (cube_info == (CubeInfo *) NULL)
2055
0
    ThrowBinaryException3(ResourceLimitError,MemoryAllocationFailed,
2056
1.31k
      UnableToMapImage);
2057
1.31k
  status=ClassifyImageColors(cube_info,map_image,&image->exception);
2058
1.31k
  if (status != MagickFail)
2059
1.31k
    {
2060
      /*
2061
        Classify image colors from the reference image.
2062
      */
2063
1.31k
      quantize_info.number_colors=cube_info->colors;
2064
1.31k
      status=AssignImageColors(cube_info,image);
2065
1.31k
    }
2066
1.31k
  DestroyCubeInfo(cube_info);
2067
1.31k
  return(status);
2068
1.31k
}
2069

2070
/*
2071
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2072
%                                                                             %
2073
%                                                                             %
2074
%                                                                             %
2075
%   M a p I m a g e s                                                         %
2076
%                                                                             %
2077
%                                                                             %
2078
%                                                                             %
2079
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2080
%
2081
%  MapImages() replaces the colors of a sequence of images with the closest
2082
%  color from a reference image. If the reference image does not contain a
2083
%  colormap, then a colormap will be created based on existing colors in the
2084
%  reference image. The order and number of colormap entries does not match
2085
%  the reference image.  If the order and number of colormap entries needs to
2086
%  match the reference image, then the ReplaceImageColormap() function may be
2087
%  used after invoking MapImages() in order to apply the reference colormap.
2088
%
2089
%  The format of the MapImage method is:
2090
%
2091
%      unsigned int MapImages(Image *images,Image *map_image,
2092
%        const unsigned int dither)
2093
%
2094
%  A description of each parameter follows:
2095
%
2096
%    o image: Specifies a pointer to a set of Image structures.
2097
%
2098
%    o map_image: Specifies a pointer to an Image structure.  Reduce
2099
%      image to a set of colors represented by this image.
2100
%
2101
%    o dither: Set this integer value to something other than zero to
2102
%      dither the quantized image.
2103
%
2104
%
2105
*/
2106
MagickExport MagickPassFail MapImages(Image *images,const Image *map_image,
2107
  const unsigned int dither)
2108
0
{
2109
0
  CubeInfo
2110
0
    *cube_info;
2111
2112
0
  Image
2113
0
    *image;
2114
2115
0
  QuantizeInfo
2116
0
    quantize_info;
2117
2118
0
  MagickPassFail
2119
0
    status;
2120
2121
0
  assert(images != (Image *) NULL);
2122
0
  assert(images->signature == MagickSignature);
2123
0
  GetQuantizeInfo(&quantize_info);
2124
0
  quantize_info.dither=dither;
2125
0
  image=images;
2126
0
  if (map_image == (Image *) NULL)
2127
0
    {
2128
      /*
2129
        Create a global colormap for an image sequence.
2130
      */
2131
0
      for ( ; image != (Image *) NULL; image=image->next)
2132
0
        if (image->matte)
2133
0
          quantize_info.colorspace=TransparentColorspace;
2134
0
      status=QuantizeImages(&quantize_info,images);
2135
0
      return(status);
2136
0
    }
2137
  /*
2138
    Classify image colors from the reference image.
2139
  */
2140
0
  cube_info=GetCubeInfo(&quantize_info,8);
2141
0
  if (cube_info == (CubeInfo *) NULL)
2142
0
    ThrowBinaryException3(ResourceLimitError,MemoryAllocationFailed,
2143
0
      UnableToMapImageSequence);
2144
0
  status=ClassifyImageColors(cube_info,map_image,&image->exception);
2145
0
  if (status != MagickFail)
2146
0
    {
2147
      /*
2148
        Classify image colors from the reference image.
2149
      */
2150
0
      quantize_info.number_colors=cube_info->colors;
2151
0
      for (image=images; image != (Image *) NULL; image=image->next)
2152
0
      {
2153
0
        quantize_info.colorspace=image->matte ? TransparentColorspace :
2154
0
          RGBColorspace;
2155
0
        status=AssignImageColors(cube_info,image);
2156
0
        if (status == MagickFail)
2157
0
          break;
2158
0
      }
2159
0
    }
2160
0
  DestroyCubeInfo(cube_info);
2161
0
  return(status);
2162
0
}
2163

2164
/*
2165
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2166
%                                                                             %
2167
%                                                                             %
2168
%                                                                             %
2169
%   O r d e r e d D i t h e r I m a g e                                       %
2170
%                                                                             %
2171
%                                                                             %
2172
%                                                                             %
2173
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2174
%
2175
%  OrderedDitherImage() uses the ordered dithering technique of reducing color
2176
%  images to monochrome using positional information to retain as much
2177
%  information as possible.
2178
%
2179
%  The format of the OrderedDitherImage method is:
2180
%
2181
%      unsigned int OrderedDitherImage(Image *image)
2182
%
2183
%  A description of each parameter follows.
2184
%
2185
%    o image: Specifies a pointer to an Image structure;  returned from
2186
%      ReadImage.
2187
%
2188
%
2189
*/
2190
MagickExport MagickPassFail OrderedDitherImage(Image *image)
2191
0
{
2192
0
#define DitherImageText "[%s] Ordered dither..."
2193
2194
0
  static const Quantum
2195
0
    DitherMatrix[8][8] =
2196
0
    {
2197
0
      {   0, 192,  48, 240,  12, 204,  60, 252 },
2198
0
      { 128,  64, 176, 112, 140,  76, 188, 124 },
2199
0
      {  32, 224,  16, 208,  44, 236,  28, 220 },
2200
0
      { 160,  96, 144,  80, 172, 108, 156,  92 },
2201
0
      {   8, 200,  56, 248,   4, 196,  52, 244 },
2202
0
      { 136,  72, 184, 120, 132,  68, 180, 116 },
2203
0
      {  40, 232,  24, 216,  36, 228,  20, 212 },
2204
0
      { 168, 104, 152,  88, 164, 100, 148,  84 }
2205
0
    };
2206
2207
0
  long
2208
0
    y;
2209
2210
0
  MagickPassFail
2211
0
    status=MagickPass;
2212
2213
  /*
2214
    Initialize colormap.
2215
  */
2216
0
  (void) NormalizeImage(image);
2217
0
  if (!AllocateImageColormap(image,2))
2218
0
    ThrowBinaryException3(ResourceLimitError,MemoryAllocationFailed,
2219
0
      UnableToDitherImage);
2220
  /*
2221
    Dither image with the ordered dithering technique.
2222
    FIXME: Use OpenMP?
2223
  */
2224
0
  for (y=0; y < (long) image->rows; y++)
2225
0
  {
2226
0
    IndexPacket
2227
0
      index;
2228
2229
0
    register IndexPacket
2230
0
      *indexes;
2231
2232
0
    register long
2233
0
      x;
2234
2235
0
    register PixelPacket
2236
0
      *q;
2237
2238
0
    q=GetImagePixels(image,0,y,image->columns,1);
2239
0
    if (q == (PixelPacket *) NULL)
2240
0
      {
2241
0
        status=MagickFail;
2242
0
        break;
2243
0
      }
2244
0
    indexes=AccessMutableIndexes(image);
2245
0
    for (x=0; x < (long) image->columns; x++)
2246
0
    {
2247
0
      index=(Quantum) (PixelIntensityToQuantum(q) >
2248
0
        ScaleCharToQuantum(DitherMatrix[y & 0x07][x & 0x07]) ? 1 : 0);
2249
0
      indexes[x]=index;
2250
0
      q->red=image->colormap[index].red;
2251
0
      q->green=image->colormap[index].green;
2252
0
      q->blue=image->colormap[index].blue;
2253
0
      q++;
2254
0
    }
2255
0
    if (!SyncImagePixels(image))
2256
0
      {
2257
0
        status=MagickFail;
2258
0
        break;
2259
0
      }
2260
0
    if (QuantumTick(y,image->rows))
2261
0
      if (!MagickMonitorFormatted(y,image->rows,&image->exception,
2262
0
                                  DitherImageText,image->filename))
2263
0
        {
2264
0
          status=MagickFail;
2265
0
          break;
2266
0
        }
2267
0
  }
2268
0
  return(status);
2269
0
}
2270

2271
/*
2272
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2273
%                                                                             %
2274
%                                                                             %
2275
%                                                                             %
2276
+   P r u n e C h i l d                                                       %
2277
%                                                                             %
2278
%                                                                             %
2279
%                                                                             %
2280
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2281
%
2282
%  PruneChild() deletes the given node and merges its statistics into its
2283
%  parent.
2284
%
2285
%  This is a recursive function.
2286
%
2287
%  The format of the PruneSubtree method is:
2288
%
2289
%      PruneChild(CubeInfo *cube_info,const NodeInfo *node_info)
2290
%
2291
%  A description of each parameter follows.
2292
%
2293
%    o cube_info: A pointer to the Cube structure.
2294
%
2295
%    o node_info: pointer to node in color cube tree that is to be pruned.
2296
%
2297
%
2298
*/
2299
static void PruneChild(CubeInfo *cube_info,const NodeInfo *node_info)
2300
781k
{
2301
781k
  NodeInfo
2302
781k
    *parent;
2303
2304
781k
  register unsigned int
2305
781k
    id;
2306
2307
  /*
2308
    Traverse any children.
2309
  */
2310
7.03M
  for (id=0; id < MaxTreeDepth; id++)
2311
6.25M
    if (node_info->child[id] != (NodeInfo *) NULL)
2312
2.68k
      PruneChild(cube_info,node_info->child[id]);
2313
  /*
2314
    Merge color statistics into parent.
2315
  */
2316
781k
  parent=node_info->parent;
2317
781k
  parent->number_unique+=node_info->number_unique;
2318
781k
  parent->total_red+=node_info->total_red;
2319
781k
  parent->total_green+=node_info->total_green;
2320
781k
  parent->total_blue+=node_info->total_blue;
2321
781k
  parent->child[node_info->id]=(NodeInfo *) NULL;
2322
781k
  cube_info->nodes--;
2323
781k
}
2324

2325
/*
2326
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2327
%                                                                             %
2328
%                                                                             %
2329
%                                                                             %
2330
+  P r u n e L e v e l                                                        %
2331
%                                                                             %
2332
%                                                                             %
2333
%                                                                             %
2334
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2335
%
2336
%  PruneLevel() deletes all nodes at the bottom level of the color tree merging
2337
%  their color statistics into their parent node.
2338
%
2339
%  This is a recursive function.
2340
%
2341
%  The format of the PruneLevel method is:
2342
%
2343
%      PruneLevel(CubeInfo *cube_info,const NodeInfo *node_info)
2344
%
2345
%  A description of each parameter follows.
2346
%
2347
%    o cube_info: A pointer to the Cube structure.
2348
%
2349
%    o node_info: pointer to node in color cube tree that is to be pruned.
2350
%
2351
%
2352
*/
2353
static void PruneLevel(CubeInfo *cube_info,const NodeInfo *node_info)
2354
0
{
2355
0
  register unsigned int
2356
0
    id;
2357
2358
  /*
2359
    Traverse any children.
2360
  */
2361
0
  for (id=0; id < MaxTreeDepth; id++)
2362
0
    if (node_info->child[id] != (NodeInfo *) NULL)
2363
0
      PruneLevel(cube_info,node_info->child[id]);
2364
0
  if (node_info->level == cube_info->depth)
2365
0
    PruneChild(cube_info,node_info);
2366
0
}
2367

2368
/*
2369
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2370
%                                                                             %
2371
%                                                                             %
2372
%                                                                             %
2373
+  P r u n e T o C u b e D e p t h                                            %
2374
%                                                                             %
2375
%                                                                             %
2376
%                                                                             %
2377
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2378
%
2379
%  PruneToCubeDepth() deletes any nodes ar a depth greater than
2380
%  cube_info->depth while merging their color statistics into their parent
2381
%  node.
2382
%
2383
%  This is a recursive function.
2384
%
2385
%  The format of the PruneToCubeDepth method is:
2386
%
2387
%      PruneToCubeDepth(CubeInfo *cube_info,const NodeInfo *node_info)
2388
%
2389
%  A description of each parameter follows.
2390
%
2391
%    o cube_info: A pointer to the Cube structure.
2392
%
2393
%    o node_info: pointer to node in color cube tree that is to be pruned.
2394
%
2395
%
2396
*/
2397
static void PruneToCubeDepth(CubeInfo *cube_info,const NodeInfo *node_info)
2398
659k
{
2399
659k
  register unsigned int
2400
659k
    id;
2401
2402
  /*
2403
    Traverse any children.
2404
  */
2405
5.93M
  for (id=0; id < MaxTreeDepth; id++)
2406
5.27M
    if (node_info->child[id] != (NodeInfo *) NULL)
2407
658k
      PruneToCubeDepth(cube_info,node_info->child[id]);
2408
659k
  if (node_info->level > cube_info->depth)
2409
269k
    PruneChild(cube_info,node_info);
2410
659k
}
2411

2412
/*
2413
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2414
%                                                                             %
2415
%                                                                             %
2416
%                                                                             %
2417
%  Q u a n t i z e I m a g e                                                  %
2418
%                                                                             %
2419
%                                                                             %
2420
%                                                                             %
2421
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2422
%
2423
%  QuantizeImage() analyzes the colors within a reference image and chooses a
2424
%  fixed number of colors to represent the image.  The goal of the algorithm
2425
%  is to minimize the color difference between the input and output image while
2426
%  minimizing the processing time.
2427
%
2428
%  The format of the QuantizeImage method is:
2429
%
2430
%      unsigned int QuantizeImage(const QuantizeInfo *quantize_info,
2431
%        Image *image)
2432
%
2433
%  A description of each parameter follows:
2434
%
2435
%    o quantize_info: Specifies a pointer to an QuantizeInfo structure.
2436
%
2437
%    o image: Specifies a pointer to an Image structure.
2438
%
2439
*/
2440
MagickExport MagickPassFail QuantizeImage(const QuantizeInfo *quantize_info,
2441
  Image *image)
2442
18.8k
{
2443
18.8k
  CubeInfo
2444
18.8k
    *cube_info;
2445
2446
18.8k
  MagickPassFail
2447
18.8k
    status;
2448
2449
18.8k
  unsigned long
2450
18.8k
    depth,
2451
18.8k
    number_colors;
2452
2453
18.8k
  assert(quantize_info != (const QuantizeInfo *) NULL);
2454
18.8k
  assert(quantize_info->signature == MagickSignature);
2455
18.8k
  assert(image != (Image *) NULL);
2456
18.8k
  assert(image->signature == MagickSignature);
2457
18.8k
  number_colors=quantize_info->number_colors;
2458
18.8k
  if (number_colors == 0)
2459
0
    number_colors=MaxColormapSize;
2460
18.8k
  if (number_colors > MaxColormapSize)
2461
0
    number_colors=MaxColormapSize;
2462
  /*
2463
    For grayscale images, use a fast translation to PseudoClass,
2464
    which assures that the maximum number of colors is equal to, or
2465
    less than MaxColormapSize.
2466
  */
2467
18.8k
  if (IsGrayColorspace(quantize_info->colorspace))
2468
149
    (void) TransformColorspace(image,quantize_info->colorspace);
2469
18.8k
  if (IsGrayImage(image,&image->exception))
2470
4.00k
    GrayscalePseudoClassImage(image,True);
2471
  /*
2472
    If the image colors do not require further reduction, then simply
2473
    return.
2474
  */
2475
18.8k
  if ((image->storage_class == PseudoClass) &&
2476
4.24k
      (image->colors <= number_colors))
2477
4.17k
    return(MagickPass);
2478
14.6k
  depth=quantize_info->tree_depth;
2479
14.6k
  if (depth == 0)
2480
14.6k
    {
2481
14.6k
      unsigned long
2482
14.6k
        colors;
2483
2484
      /*
2485
        Depth of color tree is: Log4(colormap size)+2.
2486
      */
2487
14.6k
      colors=number_colors;
2488
87.8k
      for (depth=1; colors != 0; depth++)
2489
73.2k
        colors>>=2;
2490
14.6k
      if (quantize_info->dither)
2491
14.6k
        depth--;
2492
14.6k
      if (image->storage_class == PseudoClass)
2493
69
        depth+=2;
2494
14.6k
    }
2495
  /*
2496
    Initialize color cube.
2497
  */
2498
14.6k
  cube_info=GetCubeInfo(quantize_info,depth);
2499
14.6k
  if (cube_info == (CubeInfo *) NULL)
2500
0
    ThrowBinaryException3(ResourceLimitError,
2501
14.6k
      MemoryAllocationFailed,UnableToQuantizeImage);
2502
14.6k
  if (quantize_info->colorspace != RGBColorspace)
2503
0
    (void) TransformColorspace(image,quantize_info->colorspace);
2504
14.6k
  status=ClassifyImageColors(cube_info,image,&image->exception);
2505
14.6k
  if (status != MagickFail)
2506
14.6k
    {
2507
      /*
2508
        Reduce the number of colors in the image.
2509
      */
2510
14.6k
      ReduceImageColors(image->filename,cube_info,number_colors,&image->exception);
2511
14.6k
      status=AssignImageColors(cube_info,image);
2512
14.6k
      if (quantize_info->colorspace != RGBColorspace)
2513
0
        (void) TransformColorspace(image,quantize_info->colorspace);
2514
14.6k
    }
2515
14.6k
  DestroyCubeInfo(cube_info);
2516
14.6k
  return(status);
2517
14.6k
}
2518

2519
/*
2520
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2521
%                                                                             %
2522
%                                                                             %
2523
%                                                                             %
2524
%   Q u a n t i z e I m a g e s                                               %
2525
%                                                                             %
2526
%                                                                             %
2527
%                                                                             %
2528
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2529
%
2530
%  QuantizeImages() analyzes the colors within a set of reference images and
2531
%  chooses a fixed number of colors to represent the set.  The goal of the
2532
%  algorithm is to minimize the color difference between the input and output
2533
%  images while minimizing the processing time.
2534
%
2535
%  The format of the QuantizeImages method is:
2536
%
2537
%      unsigned int QuantizeImages(const QuantizeInfo *quantize_info,
2538
%        Image *images)
2539
%
2540
%  A description of each parameter follows:
2541
%
2542
%    o quantize_info: Specifies a pointer to an QuantizeInfo structure.
2543
%
2544
%    o images: Specifies a pointer to a list of Image structures.
2545
%
2546
%
2547
*/
2548
MagickExport MagickPassFail QuantizeImages(const QuantizeInfo *quantize_info,
2549
  Image *images)
2550
0
{
2551
0
  CubeInfo
2552
0
    *cube_info;
2553
2554
0
  int
2555
0
    depth;
2556
2557
0
  MonitorHandler
2558
0
    handler;
2559
2560
0
  Image
2561
0
    *image;
2562
2563
0
  register long
2564
0
    i;
2565
2566
0
  unsigned int
2567
0
    status;
2568
2569
0
  unsigned long
2570
0
    number_colors,
2571
0
    number_images;
2572
2573
0
  assert(quantize_info != (const QuantizeInfo *) NULL);
2574
0
  assert(quantize_info->signature == MagickSignature);
2575
0
  assert(images != (Image *) NULL);
2576
0
  assert(images->signature == MagickSignature);
2577
0
  if (images->next == (Image *) NULL)
2578
0
    {
2579
      /*
2580
        Handle a single image with QuantizeImage.
2581
      */
2582
0
      status=QuantizeImage(quantize_info,images);
2583
0
      return(status);
2584
0
    }
2585
0
  status=False;
2586
0
  image=images;
2587
0
  number_colors=quantize_info->number_colors;
2588
0
  if (number_colors == 0)
2589
0
    number_colors=MaxColormapSize;
2590
0
  if (number_colors > MaxColormapSize)
2591
0
    number_colors=MaxColormapSize;
2592
0
  depth=quantize_info->tree_depth;
2593
0
  if (depth == 0)
2594
0
    {
2595
0
      int
2596
0
        pseudo_class;
2597
2598
0
      unsigned long
2599
0
        colors;
2600
2601
      /*
2602
        Depth of color tree is: Log4(colormap size)+2.
2603
      */
2604
0
      colors=number_colors;
2605
0
      for (depth=1; colors != 0; depth++)
2606
0
        colors>>=2;
2607
0
      if (quantize_info->dither)
2608
0
        depth--;
2609
0
      pseudo_class=True;
2610
0
      for (image=images; image != (Image *) NULL; image=image->next)
2611
0
        pseudo_class|=(image->storage_class == PseudoClass);
2612
0
      if (pseudo_class)
2613
0
        depth+=2;
2614
0
    }
2615
  /*
2616
    Initialize color cube.
2617
  */
2618
0
  cube_info=GetCubeInfo(quantize_info,depth);
2619
0
  if (cube_info == (CubeInfo *) NULL)
2620
0
    ThrowBinaryException3(ResourceLimitError,MemoryAllocationFailed,
2621
0
      UnableToQuantizeImageSequence);
2622
0
  image=images;
2623
0
  for (i=0; image != (Image *) NULL; i++)
2624
0
  {
2625
0
    if (quantize_info->colorspace != RGBColorspace)
2626
0
      (void) TransformColorspace(image,quantize_info->colorspace);
2627
0
    image=image->next;
2628
0
  }
2629
0
  number_images=i;
2630
0
  image=images;
2631
0
  for (i=0; image != (Image *) NULL; i++)
2632
0
  {
2633
0
    handler=SetMonitorHandler((MonitorHandler) NULL);
2634
0
    status=ClassifyImageColors(cube_info,image,&image->exception);
2635
0
    if (status == MagickFail)
2636
0
      break;
2637
0
    image=image->next;
2638
0
    (void) SetMonitorHandler(handler);
2639
0
    if ((image != (Image *) NULL) &&
2640
0
        (!MagickMonitorFormatted(i,number_images,&image->exception,
2641
0
                                 ClassifyImageText,image->filename)))
2642
0
      break;
2643
0
  }
2644
0
  if (status != MagickFail)
2645
0
    {
2646
      /*
2647
        Reduce the number of colors in an image sequence.
2648
      */
2649
0
      ReduceImageColors(image->filename,cube_info,number_colors,&image->exception);
2650
0
      image=images;
2651
0
      for (i=0; image != (Image *) NULL; i++)
2652
0
      {
2653
0
        handler=SetMonitorHandler((MonitorHandler) NULL);
2654
0
        status=AssignImageColors(cube_info,image);
2655
0
        if (status == MagickFail)
2656
0
          break;
2657
0
        if (quantize_info->colorspace != RGBColorspace)
2658
0
          (void) TransformColorspace(image,quantize_info->colorspace);
2659
0
        image=image->next;
2660
0
        (void) SetMonitorHandler(handler);
2661
0
        if ((image != (Image *) NULL) &&
2662
0
            (!MagickMonitorFormatted(i,number_images,&image->exception,
2663
0
                                     AssignImageText,image->filename)))
2664
0
          {
2665
0
            status=MagickFail;
2666
0
            break;
2667
0
          }
2668
0
      }
2669
0
    }
2670
0
  DestroyCubeInfo(cube_info);
2671
0
  return(status);
2672
0
}
2673

2674
/*
2675
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2676
%                                                                             %
2677
%                                                                             %
2678
%                                                                             %
2679
+   R e d u c e                                                               %
2680
%                                                                             %
2681
%                                                                             %
2682
%                                                                             %
2683
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2684
%
2685
%  Reduce() traverses the color cube tree and prunes any node whose
2686
%  quantization error falls below a particular threshold.
2687
%
2688
%  This is a recursive function.
2689
%
2690
%  The format of the Reduce method is:
2691
%
2692
%      Reduce(CubeInfo *cube_info,const NodeInfo *node_info)
2693
%
2694
%  A description of each parameter follows.
2695
%
2696
%    o cube_info: A pointer to the Cube structure.
2697
%
2698
%    o node_info: pointer to node in color cube tree that is to be pruned.
2699
%
2700
%
2701
*/
2702
static void Reduce(CubeInfo *cube_info,const NodeInfo *node_info)
2703
631M
{
2704
631M
  register unsigned int
2705
631M
    id;
2706
2707
  /*
2708
    Traverse any children.
2709
  */
2710
5.68G
  for (id=0; id < MaxTreeDepth; id++)
2711
5.05G
    if (node_info->child[id] != (NodeInfo *) NULL)
2712
631M
      Reduce(cube_info,node_info->child[id]);
2713
631M
  if (node_info->quantize_error <= cube_info->pruning_threshold)
2714
509k
    PruneChild(cube_info,node_info);
2715
630M
  else
2716
630M
    {
2717
      /*
2718
        Find minimum pruning threshold.
2719
      */
2720
630M
      if (node_info->number_unique > 0)
2721
517M
        cube_info->colors++;
2722
630M
      if (node_info->quantize_error < cube_info->next_threshold)
2723
4.26M
        cube_info->next_threshold=node_info->quantize_error;
2724
630M
    }
2725
631M
}
2726

2727
/*
2728
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2729
%                                                                             %
2730
%                                                                             %
2731
%                                                                             %
2732
+   R e d u c e I m a g e C o l o r s                                         %
2733
%                                                                             %
2734
%                                                                             %
2735
%                                                                             %
2736
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2737
%
2738
%  ReduceImageColors() repeatedly prunes the tree until the number of nodes
2739
%  with n2 > 0 is less than or equal to the maximum number of colors allowed
2740
%  in the output image.  On any given iteration over the tree, it selects
2741
%  those nodes whose E value is minimal for pruning and merges their
2742
%  color statistics upward. It uses a pruning threshold, Ep, to govern
2743
%  node selection as follows:
2744
%
2745
%    Ep = 0
2746
%    while number of nodes with (n2 > 0) > required maximum number of colors
2747
%      prune all nodes such that E <= Ep
2748
%      Set Ep to minimum E in remaining nodes
2749
%
2750
%  This has the effect of minimizing any quantization error when merging
2751
%  two nodes together.
2752
%
2753
%  When a node to be pruned has offspring, the pruning procedure invokes
2754
%  itself recursively in order to prune the tree from the leaves upward.
2755
%  n2,  Sr, Sg,  and  Sb in a node being pruned are always added to the
2756
%  corresponding data in that node's parent.  This retains the pruned
2757
%  node's color characteristics for later averaging.
2758
%
2759
%  For each node, n2 pixels exist for which that node represents the
2760
%  smallest volume in RGB space containing those pixel's colors.  When n2
2761
%  > 0 the node will uniquely define a color in the output image. At the
2762
%  beginning of reduction,  n2 = 0  for all nodes except a the leaves of
2763
%  the tree which represent colors present in the input image.
2764
%
2765
%  The other pixel count, n1, indicates the total number of colors
2766
%  within the cubic volume which the node represents.  This includes n1 -
2767
%  n2  pixels whose colors should be defined by nodes at a lower level in
2768
%  the tree.
2769
%
2770
%  The format of the ReduceImageColors method is:
2771
%
2772
%      ReduceImageColors(const char *filename, CubeInfo *cube_info,
2773
%        const unsigned int number_colors, ExceptionInfo *exception)
2774
%
2775
%  A description of each parameter follows.
2776
%
2777
%    o filename: Filename for use in progress messages.
2778
%
2779
%    o cube_info: A pointer to the Cube structure.
2780
%
2781
%    o number_colors: This integer value indicates the maximum number of
2782
%      colors in the quantized image or colormap.  The actual number of
2783
%      colors allocated to the colormap may be less than this value, but
2784
%      never more.
2785
%
2786
%    o exception: Return any errors or warnings in this structure.
2787
%
2788
*/
2789
static void ReduceImageColors(const char *filename,CubeInfo *cube_info,
2790
  const unsigned long number_colors,ExceptionInfo *exception)
2791
14.6k
{
2792
405k
#define ReduceImageText "[%s] Reduce colors: %lu..."
2793
2794
14.6k
  unsigned int
2795
14.6k
    status;
2796
2797
14.6k
  unsigned long
2798
14.6k
    span;
2799
2800
14.6k
  span=cube_info->colors;
2801
14.6k
  cube_info->next_threshold=0.0;
2802
420k
  while (cube_info->colors > number_colors)
2803
405k
  {
2804
405k
    cube_info->pruning_threshold=cube_info->next_threshold;
2805
405k
    cube_info->next_threshold=cube_info->root->quantize_error-1;
2806
405k
    cube_info->colors=0;
2807
405k
    Reduce(cube_info,cube_info->root);
2808
405k
    status=MagickMonitorFormatted(span-cube_info->colors,
2809
405k
                                  (size_t) span-number_colors+1,exception,
2810
405k
                                  ReduceImageText,
2811
405k
                                  filename,
2812
405k
                                  number_colors);
2813
405k
    if (status == False)
2814
0
      break;
2815
405k
  }
2816
14.6k
}