home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / x / volume20 / imagemgc / part30 < prev    next >
Encoding:
Text File  |  1993-07-13  |  50.6 KB  |  1,577 lines

  1. Newsgroups: comp.sources.x
  2. From: cristy@eplrx7.es.duPont.com (Cristy)
  3. Subject: v20i086:  imagemagic - X11 image processing and display, Part30/38
  4. Message-ID: <1993Jul14.232132.22976@sparky.sterling.com>
  5. X-Md4-Signature: c8bcc5fa29542ed3d7f9f36880d11216
  6. Sender: chris@sparky.sterling.com (Chris Olson)
  7. Organization: Sterling Software
  8. Date: Wed, 14 Jul 1993 23:21:32 GMT
  9. Approved: chris@sterling.com
  10.  
  11. Submitted-by: cristy@eplrx7.es.duPont.com (Cristy)
  12. Posting-number: Volume 20, Issue 86
  13. Archive-name: imagemagic/part30
  14. Environment: X11
  15. Supersedes: imagemagic: Volume 13, Issue 17-37
  16.  
  17. #!/bin/sh
  18. # this is magick.30 (part 30 of ImageMagick)
  19. # do not concatenate these parts, unpack them in order with /bin/sh
  20. # file ImageMagick/quantize.c continued
  21. #
  22. if test ! -r _shar_seq_.tmp; then
  23.     echo 'Please unpack part 1 first!'
  24.     exit 1
  25. fi
  26. (read Scheck
  27.  if test "$Scheck" != 30; then
  28.     echo Please unpack part "$Scheck" next!
  29.     exit 1
  30.  else
  31.     exit 0
  32.  fi
  33. ) < _shar_seq_.tmp || exit 1
  34. if test ! -f _shar_wnt_.tmp; then
  35.     echo 'x - still skipping ImageMagick/quantize.c'
  36. else
  37. echo 'x - continuing file ImageMagick/quantize.c'
  38. sed 's/^X//' << 'SHAR_EOF' >> 'ImageMagick/quantize.c' &&
  39. %  run-length encoded format.
  40. %
  41. %  With the permission of USC Information Sciences Institute, 4676 Admiralty
  42. %  Way, Marina del Rey, California  90292, this code was adapted from module
  43. %  ALCOLS written by Paul Raveling.
  44. %
  45. %  The names of ISI and USC are not used in advertising or publicity
  46. %  pertaining to distribution of the software without prior specific
  47. %  written permission from ISI.
  48. %
  49. %
  50. */
  51. X
  52. /*
  53. X  Include declarations.
  54. */
  55. #include "display.h"
  56. #include "image.h"
  57. X
  58. /*
  59. X  Define declarations.
  60. */
  61. #define color_number  number_colors
  62. #define MaxNodes  266817
  63. #define MaxShift  8
  64. #define MaxTreeDepth  8  /* Log2(MaxRGB) */
  65. #define NodesInAList  2048
  66. X
  67. /*
  68. X  Structures.
  69. */
  70. typedef struct _Node
  71. {
  72. X  struct _Node
  73. X    *parent,
  74. X    *child[8];
  75. X
  76. X  unsigned char
  77. X    id,
  78. X    level,
  79. X    children,
  80. X    mid_red,
  81. X    mid_green,
  82. X    mid_blue;
  83. X
  84. X  unsigned long
  85. X    number_colors,
  86. X    number_unique,
  87. X    total_red,
  88. X    total_green,
  89. X    total_blue;
  90. } Node;
  91. X
  92. typedef struct _Nodes
  93. {
  94. X  Node
  95. X    nodes[NodesInAList];
  96. X
  97. X  struct _Nodes
  98. X    *next;
  99. } Nodes;
  100. X
  101. typedef struct _Cube
  102. {
  103. X  Node
  104. X    *root;
  105. X
  106. X  ColorPacket
  107. X    color,
  108. X    *colormap;
  109. X
  110. X  unsigned int
  111. X    depth;
  112. X
  113. X  unsigned long
  114. X    colors,
  115. X    pruning_threshold,
  116. X    next_pruning_threshold,
  117. X    distance,
  118. X    shift[MaxTreeDepth+1],
  119. X    squares[MaxRGB+MaxRGB+1];
  120. X
  121. X  unsigned int
  122. X    nodes,
  123. X    free_nodes,
  124. X    color_number;
  125. X
  126. X  Node
  127. X    *next_node;
  128. X
  129. X  Nodes
  130. X    *node_queue;
  131. } Cube;
  132. X
  133. /*
  134. X  Global variables.
  135. */
  136. static Cube
  137. X  cube;
  138. X
  139. /*
  140. X  External declarations.
  141. */
  142. extern char
  143. X  *client_name;
  144. X
  145. /*
  146. X  Forward declarations.
  147. */
  148. static Node
  149. X  *InitializeNode _Declare((unsigned int,unsigned int,Node *,unsigned int,
  150. X    unsigned int,unsigned int));
  151. X
  152. static unsigned int
  153. X  DitherImage _Declare((Image *));
  154. X
  155. static void
  156. X  ClosestColor _Declare((Node *)),
  157. X  Colormap _Declare((Node *)),
  158. X  PruneLevel _Declare((Node *));
  159. X
  160. /*
  161. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  162. %                                                                             %
  163. %                                                                             %
  164. %                                                                             %
  165. %  A s s i g n m e n t                                                        %
  166. %                                                                             %
  167. %                                                                             %
  168. %                                                                             %
  169. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  170. %
  171. %  Procedure Assignment generates the output image from the pruned tree.  The
  172. %  output image consists of two parts: (1)  A color map, which is an
  173. %  array of color descriptions (RGB triples) for each color present in
  174. %  the output image;  (2)  A pixel array, which represents each pixel as
  175. %  an index into the color map array.
  176. %
  177. %  First, the assignment phase makes one pass over the pruned color
  178. %  description tree to establish the image's color map.  For each node
  179. %  with n2  > 0, it divides Sr, Sg, and Sb by n2 .  This produces the
  180. %  mean color of all pixels that classify no lower than this node.  Each
  181. %  of these colors becomes an entry in the color map.
  182. %
  183. %  Finally,  the assignment phase reclassifies each pixel in the pruned
  184. %  tree to identify the deepest node containing the pixel's color.  The
  185. %  pixel's value in the pixel array becomes the index of this node's mean
  186. %  color in the color map.
  187. %
  188. %  The format of the Assignment routine is:
  189. %
  190. %      Assignment(image,dither,colorspace,optimal)
  191. %
  192. %  A description of each parameter follows.
  193. %
  194. %    o image: Specifies a pointer to an Image structure;  returned from
  195. %      ReadImage.
  196. %
  197. %    o dither: Set this integer value to something other than zero to
  198. %      dither the quantized image.  The basic strategy of dithering is to
  199. %      trade intensity resolution for spatial resolution by averaging the
  200. %      intensities of several neighboring pixels.  Images which suffer
  201. %      from severe contouring when quantized can be improved with the
  202. %      technique of dithering.  Severe contouring generally occurs when
  203. %      quantizing to very few colors, or to a poorly-chosen colormap.
  204. %      Note, dithering is a computationally expensive process and will
  205. %      increase processing time significantly.
  206. %
  207. %    o colorspace: An unsigned integer value that indicates the colorspace.
  208. %
  209. %    o optimal: An unsigned integer value greater than zero indicates that
  210. %      the optimal representation of the reference image should be returned.
  211. %
  212. %
  213. */
  214. static void Assignment(image,dither,colorspace,optimal)
  215. Image
  216. X  *image;
  217. X
  218. unsigned int
  219. X  dither,
  220. X  colorspace,
  221. X  optimal;
  222. {
  223. X  register int
  224. X    i;
  225. X
  226. X  register Node
  227. X    *node;
  228. X
  229. X  register RunlengthPacket
  230. X    *p;
  231. X
  232. X  register unsigned int
  233. X    id;
  234. X
  235. X  /*
  236. X    Allocate image colormap.
  237. X  */
  238. X  image->alpha=False;
  239. X  image->class=PseudoClass;
  240. X  if (image->colormap != (ColorPacket *) NULL)
  241. X    (void) free((char *) image->colormap);
  242. X  image->colormap=(ColorPacket *)
  243. X    malloc((unsigned int) cube.colors*sizeof(ColorPacket));
  244. X  if (image->colormap == (ColorPacket *) NULL)
  245. X    {
  246. X      Warning("unable to quantize image","memory allocation failed");
  247. X      exit(1);
  248. X    }
  249. X  if (image->signature != (char *) NULL)
  250. X    (void) free((char *) image->signature);
  251. X  image->signature=(char *) NULL;
  252. X  cube.colormap=image->colormap;
  253. X  cube.colors=0;
  254. X  Colormap(cube.root);
  255. X  image->colors=(unsigned int) cube.colors;
  256. X  if ((image->colors == 2)  && (colorspace == GRAYColorspace))
  257. X    {
  258. X      unsigned int
  259. X        polarity;
  260. X
  261. X      /*
  262. X        Monochrome image.
  263. X      */
  264. X      polarity=Intensity(image->colormap[0]) > Intensity(image->colormap[1]);
  265. X      image->colormap[polarity].red=0;
  266. X      image->colormap[polarity].green=0;
  267. X      image->colormap[polarity].blue=0;
  268. X      image->colormap[!polarity].red=MaxRGB;
  269. X      image->colormap[!polarity].green=MaxRGB;
  270. X      image->colormap[!polarity].blue=MaxRGB;
  271. X    }
  272. X  /*
  273. X    Create a reduced color image.  For the non-optimal case we trade
  274. X    accuracy for speed improvements.
  275. X  */
  276. X  if (dither)
  277. X    dither=!DitherImage(image);
  278. X  p=image->pixels;
  279. X  if (!dither)
  280. X    if (!optimal)
  281. X      for (i=0; i < image->packets; i++)
  282. X      {
  283. X        /*
  284. X          Identify the deepest node containing the pixel's color.
  285. X        */
  286. X        node=cube.root;
  287. X        for ( ; ; )
  288. X        {
  289. X          id=(p->red > node->mid_red ? 1 : 0) |
  290. X            (p->green > node->mid_green ? 1 : 0) << 1 |
  291. X            (p->blue > node->mid_blue ? 1 : 0) << 2;
  292. X          if ((node->children & (1 << id)) == 0)
  293. X            break;
  294. X          node=node->child[id];
  295. X        }
  296. X        p->index=(unsigned short) node->color_number;
  297. X        p++;
  298. X      }
  299. X    else
  300. X      for (i=0; i < image->packets; i++)
  301. X      {
  302. X        /*
  303. X          Identify the deepest node containing the pixel's color.
  304. X        */
  305. X        node=cube.root;
  306. X        for ( ; ; )
  307. X        {
  308. X          id=(p->red > node->mid_red ? 1 : 0) |
  309. X            (p->green > node->mid_green ? 1 : 0) << 1 |
  310. X            (p->blue > node->mid_blue ? 1 : 0) << 2;
  311. X          if ((node->children & (1 << id)) == 0)
  312. X            break;
  313. X          node=node->child[id];
  314. X        }
  315. X        /*
  316. X          Find closest color among siblings and their children.
  317. X        */
  318. X        cube.color.red=p->red;
  319. X        cube.color.green=p->green;
  320. X        cube.color.blue=p->blue;
  321. X        cube.distance=(unsigned long) (~0);
  322. X        ClosestColor(node->parent);
  323. X        p->index=cube.color_number;
  324. X        p++;
  325. X      }
  326. }
  327. X
  328. /*
  329. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  330. %                                                                             %
  331. %                                                                             %
  332. %                                                                             %
  333. %  C l a s s i f i c a t i o n                                                %
  334. %                                                                             %
  335. %                                                                             %
  336. %                                                                             %
  337. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  338. %
  339. %  Procedure Classification begins by initializing a color description tree
  340. %  of sufficient depth to represent each possible input color in a leaf.
  341. %  However, it is impractical to generate a fully-formed color
  342. %  description tree in the classification phase for realistic values of
  343. %  cmax.  If colors components in the input image are quantized to k-bit
  344. %  precision, so that cmax= 2k-1, the tree would need k levels below the
  345. %  root node to allow representing each possible input color in a leaf.
  346. %  This becomes prohibitive because the tree's total number of nodes is
  347. %  1 + sum(i=1,k,8k).
  348. %
  349. %  A complete tree would require 19,173,961 nodes for k = 8, cmax = 255.
  350. %  Therefore, to avoid building a fully populated tree, QUANTIZE: (1)
  351. %  Initializes data structures for nodes only as they are needed;  (2)
  352. %  Chooses a maximum depth for the tree as a function of the desired
  353. %  number of colors in the output image (currently log2(colormap size)).
  354. %
  355. %  For each pixel in the input image, classification scans downward from
  356. %  the root of the color description tree.  At each level of the tree it
  357. %  identifies the single node which represents a cube in RGB space
  358. %  containing It updates the following data for each such node:
  359. %
  360. %    n1 : Number of pixels whose color is contained in the RGB cube
  361. %    which this node represents;
  362. %
  363. %    n2 : Number of pixels whose color is not represented in a node at
  364. %    lower depth in the tree;  initially,  n2 = 0 for all nodes except
  365. %    leaves of the tree.
  366. %
  367. %    Sr, Sg, Sb : Sums of the red, green, and blue component values for
  368. %    all pixels not classified at a lower depth. The combination of
  369. %    these sums and n2  will ultimately characterize the mean color of a
  370. %    set of pixels represented by this node.
  371. %
  372. %  The format of the Classification routine is:
  373. %
  374. %      Classification(image)
  375. %
  376. %  A description of each parameter follows.
  377. %
  378. %    o image: Specifies a pointer to an Image structure;  returned from
  379. %      ReadImage.
  380. %
  381. %
  382. */
  383. static void Classification(image)
  384. Image
  385. X  *image;
  386. {
  387. X  register int
  388. X    i;
  389. X
  390. X  register Node
  391. X    *node;
  392. X
  393. X  register RunlengthPacket
  394. X    *p;
  395. X
  396. X  register unsigned int
  397. X    bisect,
  398. X    count,
  399. X    id,
  400. X    level;
  401. X
  402. X  p=image->pixels;
  403. X  for (i=0; i < image->packets; i++)
  404. X  {
  405. X    if (cube.nodes > MaxNodes)
  406. X      {
  407. X        /*
  408. X          Prune one level if the color tree is too large.
  409. X        */
  410. X        PruneLevel(cube.root);
  411. X        cube.depth--;
  412. X      }
  413. X    /*
  414. X      Start at the root and descend the color cube tree.
  415. X    */
  416. X    count=p->length+1;
  417. X    node=cube.root;
  418. X    for (level=1; level < cube.depth; level++)
  419. X    {
  420. X      id=(p->red > node->mid_red ? 1 : 0) |
  421. X        (p->green > node->mid_green ? 1 : 0) << 1 |
  422. X        (p->blue > node->mid_blue ? 1 : 0) << 2;
  423. X      if (node->child[id] == (Node *) NULL)
  424. X        {
  425. X          /*
  426. X            Set colors of new node to contain pixel.
  427. X          */
  428. X          node->children|=1 << id;
  429. X          bisect=(unsigned int) (1 << (MaxTreeDepth-level)) >> 1;
  430. X          node->child[id]=InitializeNode(id,level,node,
  431. X            node->mid_red+(id & 1 ? bisect : -bisect),
  432. X            node->mid_green+(id & 2 ? bisect : -bisect),
  433. X            node->mid_blue+(id & 4 ? bisect : -bisect));
  434. X          if (node->child[id] == (Node *) NULL)
  435. X            {
  436. X              Warning("unable to quantize image","memory allocation failed");
  437. X              exit(1);
  438. X            }
  439. X          if (level == (cube.depth-1))
  440. X            cube.colors++;
  441. X        }
  442. X      /*
  443. X        Record the number of colors represented by this node.  Shift by level
  444. X        in the color description tree.
  445. X      */
  446. X      node=node->child[id];
  447. X      node->number_colors+=count << cube.shift[level];
  448. X    }
  449. X    /*
  450. X      Increment unique color count and sum RGB values for this leaf for later
  451. X      derivation of the mean cube color.
  452. X    */
  453. X    node->number_unique+=count;
  454. X    node->total_red+=p->red*count;
  455. X    node->total_green+=p->green*count;
  456. X    node->total_blue+=p->blue*count;
  457. X    p++;
  458. X  }
  459. }
  460. X
  461. /*
  462. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  463. %                                                                             %
  464. %                                                                             %
  465. %                                                                             %
  466. %  C l o s e s t C o l o r                                                    %
  467. %                                                                             %
  468. %                                                                             %
  469. %                                                                             %
  470. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  471. %
  472. %  Procedure ClosestColor traverses the color cube tree at a particular node
  473. %  and determines which colormap entry best represents the input color.
  474. %
  475. %  The format of the ClosestColor routine is:
  476. %
  477. %      ClosestColor(node)
  478. %
  479. %  A description of each parameter follows.
  480. %
  481. %    o node: The address of a structure of type Node which points to a
  482. %      node in the color cube tree that is to be pruned.
  483. %
  484. %
  485. */
  486. static void ClosestColor(node)
  487. register Node
  488. X  *node;
  489. {
  490. X  register unsigned int
  491. X    id;
  492. X
  493. X  /*
  494. X    Traverse any children.
  495. X  */
  496. X  if (node->children != 0)
  497. X    for (id=0; id < 8; id++)
  498. X      if (node->children & (1 << id))
  499. X        ClosestColor(node->child[id]);
  500. X  if (node->number_unique != 0)
  501. X    {
  502. X      register ColorPacket
  503. X        *color;
  504. X
  505. X      register unsigned int
  506. X        blue_distance,
  507. X        green_distance,
  508. X        red_distance;
  509. X
  510. X      register unsigned long
  511. X        distance;
  512. X
  513. X      /*
  514. X        Determine if this color is "closest".
  515. X      */
  516. X      color=cube.colormap+node->color_number;
  517. X      red_distance=(int) color->red-(int) cube.color.red+MaxRGB;
  518. X      green_distance=(int) color->green-(int) cube.color.green+MaxRGB;
  519. X      blue_distance=(int) color->blue-(int) cube.color.blue+MaxRGB;
  520. X      distance=cube.squares[red_distance]+cube.squares[green_distance]+
  521. X        cube.squares[blue_distance];
  522. X      if (distance < cube.distance)
  523. X        {
  524. X          cube.distance=distance;
  525. X          cube.color_number=(unsigned short) node->color_number;
  526. X        }
  527. X    }
  528. }
  529. X
  530. /*
  531. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  532. %                                                                             %
  533. %                                                                             %
  534. %                                                                             %
  535. %  C o l o r m a p                                                            %
  536. %                                                                             %
  537. %                                                                             %
  538. %                                                                             %
  539. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  540. %
  541. %  Procedure Colormap traverses the color cube tree and notes each colormap
  542. %  entry.  A colormap entry is any node in the color cube tree where the
  543. %  number of unique colors is not zero.
  544. %
  545. %  The format of the Colormap routine is:
  546. %
  547. %      Colormap(node)
  548. %
  549. %  A description of each parameter follows.
  550. %
  551. %    o node: The address of a structure of type Node which points to a
  552. %      node in the color cube tree that is to be pruned.
  553. %
  554. %
  555. */
  556. static void Colormap(node)
  557. register Node
  558. X  *node;
  559. {
  560. X  register unsigned int
  561. X    id;
  562. X
  563. X  /*
  564. X    Traverse any children.
  565. X  */
  566. X  if (node->children != 0)
  567. X    for (id=0; id < 8; id++)
  568. X      if (node->children & (1 << id))
  569. X        Colormap(node->child[id]);
  570. X  if (node->number_unique > 0)
  571. X    {
  572. X      /*
  573. X        Colormap entry is defined by the mean color in this cube.
  574. X      */
  575. X      cube.colormap[cube.colors].red=(unsigned char)
  576. X        ((node->total_red+(node->number_unique >> 1))/node->number_unique);
  577. X      cube.colormap[cube.colors].green=(unsigned char)
  578. X        ((node->total_green+(node->number_unique >> 1))/node->number_unique);
  579. X      cube.colormap[cube.colors].blue=(unsigned char)
  580. X        ((node->total_blue+(node->number_unique >> 1))/node->number_unique);
  581. X      node->color_number=cube.colors++;
  582. X    }
  583. }
  584. X
  585. /*
  586. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  587. %                                                                             %
  588. %                                                                             %
  589. %                                                                             %
  590. %  D i t h e r I m a g e                                                      %
  591. %                                                                             %
  592. %                                                                             %
  593. %                                                                             %
  594. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  595. %
  596. %  Procedure DitherImage uses the Floyd-Steinberg algorithm to dither the
  597. %  image.  Refer to "An Adaptive Algorithm for Spatial GreySscale", Robert W.
  598. %  Floyd and Louis Steinberg, Proceedings of the S.I.D., Volume 17(2), 1976.
  599. %
  600. %  First find the closest representation to the reference pixel color in the
  601. %  colormap, the node pixel is assigned this color.  Next, the colormap color
  602. %  is subtracted from the reference pixels color, this represents the
  603. %  quantization error.  Various amounts of this error are added to the pixels
  604. %  ahead and below the node pixel to correct for this error.  The error
  605. %  proportions are:
  606. %
  607. %            P     7/16
  608. %      3/16  5/16  1/16
  609. %
  610. %  The error is distributed left-to-right for even scanlines and right-to-left
  611. %  for odd scanlines.
  612. %
  613. %  The format of the DitherImage routine is:
  614. %
  615. %      DitherImage(image)
  616. %
  617. %  A description of each parameter follows.
  618. %
  619. %    o image: Specifies a pointer to an Image structure;  returned from
  620. %      ReadImage.
  621. %
  622. %
  623. */
  624. static unsigned int DitherImage(image)
  625. Image
  626. X  *image;
  627. {
  628. X  typedef struct _ScaledColorPacket
  629. X  {
  630. X    int
  631. X      red,
  632. X      green,
  633. X      blue;
  634. X  } ScaledColorPacket;
  635. X
  636. X  int
  637. X    *cache,
  638. X    odd_scanline;
  639. X
  640. X  register int
  641. X    blue_error,
  642. X    green_error,
  643. X    red_error,
  644. X    step;
  645. X
  646. X  register Node
  647. X    *node;
  648. X
  649. X  register RunlengthPacket
  650. X    *p,
  651. X    *q;
  652. X
  653. X  register ScaledColorPacket
  654. X    *cs,
  655. X    *ns;
  656. X
  657. X  register unsigned char
  658. X    *range_limit;
  659. X
  660. X  register unsigned int
  661. X    id;
  662. X
  663. X  ScaledColorPacket
  664. X    *scanline;
  665. X
  666. X  unsigned char
  667. X    blue,
  668. X    green,
  669. X    *range_table,
  670. X    red;
  671. X
  672. X  unsigned int
  673. X    i,
  674. X    x,
  675. X    y;
  676. X
  677. X  unsigned short
  678. X    index;
  679. X
  680. X  /*
  681. X    Image must be uncompressed.
  682. X  */
  683. X  if (!UncompressImage(image))
  684. X    return(True);
  685. X  /*
  686. X    Allocate the cache & scanline buffers to keep track of quantization error.
  687. X  */
  688. X  cache=(int *) malloc((1 << 18)*sizeof(int));
  689. X  range_table=(unsigned char *) malloc(3*(MaxRGB+1)*sizeof(unsigned char));
  690. X  scanline=(ScaledColorPacket *)
  691. X    malloc(2*(image->columns+2)*sizeof(ScaledColorPacket));
  692. X  if ((cache == (int *) NULL) || (range_table == (unsigned char *) NULL) ||
  693. X      (scanline == (ScaledColorPacket *) NULL))
  694. X    {
  695. X      Warning("unable to dither image","memory allocation failed");
  696. X      return(True);
  697. X    }
  698. X  /*
  699. X    Initialize tables.
  700. X  */
  701. X  for (i=0; i < (1 << 18); i++)
  702. X    cache[i]=(-1);
  703. X  for (i=0; i <= MaxRGB; i++)
  704. X  {
  705. X    range_table[i]=0;
  706. X    range_table[i+(MaxRGB+1)]=(unsigned char) i;
  707. X    range_table[i+(MaxRGB+1)*2]=MaxRGB;
  708. X  }
  709. X  range_limit=range_table+(MaxRGB+1);
  710. X  /*
  711. X    Preload first scanline.
  712. X  */
  713. X  p=image->pixels;
  714. X  cs=scanline+1;
  715. X  for (i=0; i < image->columns; i++)
  716. X  {
  717. X    cs->red=p->red;
  718. X    cs->green=p->green;
  719. X    cs->blue=p->blue;
  720. X    p++;
  721. X    cs++;
  722. X  }
  723. X  odd_scanline=False;
  724. X  for (y=0; y < image->rows; y++)
  725. X  {
  726. X    if (y < (image->rows-1))
  727. X      {
  728. X        /*
  729. X          Read another scanline.
  730. X        */
  731. X        ns=scanline+1;
  732. X        if (!odd_scanline)
  733. X          ns+=(image->columns+2);
  734. X        for (i=0; i < image->columns; i++)
  735. X        {
  736. X          ns->red=p->red;
  737. X          ns->green=p->green;
  738. X          ns->blue=p->blue;
  739. X          p++;
  740. X          ns++;
  741. X        }
  742. X      }
  743. X    if (!odd_scanline)
  744. X      {
  745. X        /*
  746. X          Distribute error left-to-right for even scanlines.
  747. X        */
  748. X        q=image->pixels+image->columns*y;
  749. X        cs=scanline+1;
  750. X        ns=scanline+(image->columns+2)+1;
  751. X        step=1;
  752. X      }
  753. X    else
  754. X      {
  755. X        /*
  756. X          Distribute error right-to-left for odd scanlines.
  757. X        */
  758. X        q=image->pixels+image->columns*y+(image->columns-1);
  759. X        cs=scanline+(image->columns+2)+(image->columns-1)+1;
  760. X        ns=scanline+(image->columns-1)+1;
  761. X        step=(-1);
  762. X      }
  763. X    for (x=0; x < image->columns; x++)
  764. X    {
  765. X      red=range_limit[cs->red];
  766. X      green=range_limit[cs->green];
  767. X      blue=range_limit[cs->blue];
  768. X      i=(red >> 2) << 12 | (green >> 2) << 6 | blue >> 2;
  769. X      if (cache[i] < 0)
  770. X        {
  771. X          /*
  772. X            Identify the deepest node containing the pixel's color.
  773. X          */
  774. X          node=cube.root;
  775. X          for ( ; ; )
  776. X          {
  777. X            id=(red > node->mid_red ? 1 : 0) |
  778. X              (green > node->mid_green ? 1 : 0) << 1 |
  779. X              (blue > node->mid_blue ? 1 : 0) << 2;
  780. X            if ((node->children & (1 << id)) == 0)
  781. X              break;
  782. X            node=node->child[id];
  783. X          }
  784. X          /*
  785. X            Find closest color among siblings and their children.
  786. X          */
  787. X          cube.color.red=red;
  788. X          cube.color.green=green;
  789. X          cube.color.blue=blue;
  790. X          cube.distance=(unsigned long) (~0);
  791. X          ClosestColor(node->parent);
  792. X          cache[i]=cube.color_number;
  793. X        }
  794. X      index=(unsigned short) cache[i];
  795. X      red_error=(int) red-(int) cube.colormap[index].red;
  796. X      green_error=(int) green-(int) cube.colormap[index].green;
  797. X      blue_error=(int) blue-(int) cube.colormap[index].blue;
  798. X      q->index=index;
  799. X      q+=step;
  800. X      /*
  801. X        Propagate the error in these proportions:
  802. X                Q     7/16
  803. X          3/16  5/16  1/16
  804. X      */
  805. X      cs+=step;
  806. X      cs->red+=(red_error-((red_error*9+8)/16));
  807. X      cs->green+=(green_error-((green_error*9+8)/16));
  808. X      cs->blue+=(blue_error-((blue_error*9+8)/16));
  809. X      ns-=step;
  810. X      ns->red+=(red_error*3+8)/16;
  811. X      ns->green+=(green_error*3+8)/16;
  812. X      ns->blue+=(blue_error*3+8)/16;
  813. X      ns+=step;
  814. X      ns->red+=(red_error*5+8)/16;
  815. X      ns->green+=(green_error*5+8)/16;
  816. X      ns->blue+=(blue_error*5+8)/16;
  817. X      ns+=step;
  818. X      ns->red+=(red_error+8)/16;
  819. X      ns->green+=(green_error+8)/16;
  820. X      ns->blue+=(blue_error+8)/16;
  821. X    }
  822. X    odd_scanline=!odd_scanline;
  823. X  }
  824. X  /*
  825. X    Free up memory.
  826. X  */
  827. X  (void) free((char *) scanline);
  828. X  (void) free((char *) range_table);
  829. X  (void) free((char *) cache);
  830. X  return(False);
  831. }
  832. X
  833. /*
  834. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  835. %                                                                             %
  836. %                                                                             %
  837. %                                                                             %
  838. %  I n i t i a l i z e C u b e                                                %
  839. %                                                                             %
  840. %                                                                             %
  841. %                                                                             %
  842. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  843. %
  844. %  Function InitializeCube initialize the Cube data structure.
  845. %
  846. %  The format of the InitializeCube routine is:
  847. %
  848. %      InitializeCube(number_colors,tree_depth,number_pixels,optimal)
  849. %
  850. %  A description of each parameter follows.
  851. %
  852. %    o number_colors: This integer value indicates the maximum number of
  853. %      colors in the quantized image or colormap.  Here we use this value
  854. %      to determine the depth of the color description tree.
  855. %
  856. %    o tree_depth: Normally, this integer value is zero or one.  A zero or
  857. %      one tells Quantize to choose a optimal tree depth of Log4(number_colors).
  858. %      A tree of this depth generally allows the best representation of the
  859. %      reference image with the least amount of memory and the fastest
  860. %      computational speed.  In some cases, such as an image with low color
  861. %      dispersion (a few number of colors), a value other than
  862. %      Log4(number_colors) is required.  To expand the color tree completely,
  863. %      use a value of 8.
  864. %
  865. %    o number_pixels: Specifies the number of individual pixels in the image.
  866. %
  867. %    o optimal: An unsigned integer value greater than zero indicates that
  868. %      the optimal representation of the reference image should be returned.
  869. %
  870. */
  871. static void InitializeCube(number_colors,tree_depth,number_pixels,optimal)
  872. unsigned int
  873. X  number_colors,
  874. X  tree_depth,
  875. X  number_pixels,
  876. X  optimal;
  877. {
  878. X  register int
  879. X    i;
  880. X
  881. X  static int
  882. X    log4[6] = {4, 16, 64, 256, 1024, ~0};
  883. X
  884. X  unsigned int
  885. X    level;
  886. X
  887. X  unsigned long
  888. X    max_shift;
  889. X
  890. X  /*
  891. X    Initialize tree to describe color cube.  Depth is: Log4(colormap size)+2;
  892. X  */
  893. X  cube.node_queue=(Nodes *) NULL;
  894. X  cube.nodes=0;
  895. X  cube.free_nodes=0;
  896. X  if (tree_depth > 1)
  897. X    cube.depth=Min(tree_depth,8);
  898. X  else
  899. X    {
  900. X      for (i=0; i < 6; i++)
  901. X        if (number_colors <= log4[i])
  902. X          break;
  903. X      cube.depth=i+3;
  904. X      if (!optimal)
  905. X        cube.depth--;
  906. X    }
  907. X  /*
  908. X    Initialize the shift values.
  909. X  */
  910. X  for (max_shift=0; number_pixels != 0; max_shift++)
  911. X    number_pixels<<=1;
  912. X  for (level=0; level < cube.depth; level++)
  913. X  {
  914. X    cube.shift[level]=(cube.depth-level-1) << 1;
  915. X    if (cube.shift[level] > max_shift)
  916. X      cube.shift[level]=max_shift;
  917. X  }
  918. X  /*
  919. X    Initialize the square values.
  920. X  */
  921. X  for (i=(-MaxRGB); i <= MaxRGB; i++)
  922. X    cube.squares[i+MaxRGB]=i*i;
  923. X  /*
  924. X    Initialize root node.
  925. X  */
  926. X  cube.root=InitializeNode(0,0,(Node *) NULL,(MaxRGB+1) >> 1,(MaxRGB+1) >> 1,
  927. X    (MaxRGB+1) >> 1);
  928. X  if (cube.root == (Node *) NULL)
  929. X    {
  930. X      Warning("unable to quantize image","memory allocation failed");
  931. X      exit(1);
  932. X    }
  933. X  cube.root->parent=cube.root;
  934. X  cube.root->number_colors=(unsigned long) (~0);
  935. X  cube.colors=0;
  936. }
  937. X
  938. /*
  939. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  940. %                                                                             %
  941. %                                                                             %
  942. %                                                                             %
  943. %  I n i t i a l i z e N o d e                                                %
  944. %                                                                             %
  945. %                                                                             %
  946. %                                                                             %
  947. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  948. %
  949. %  Function InitializeNode allocates memory for a new node in the color cube
  950. %  tree and presets all fields to zero.
  951. %
  952. %  The format of the InitializeNode routine is:
  953. %
  954. %      node=InitializeNode(node,id,level,mid_red,mid_green,mid_blue)
  955. %
  956. %  A description of each parameter follows.
  957. %
  958. %    o node: The InitializeNode routine returns this integer address.
  959. %
  960. %    o id: Specifies the child number of the node.
  961. %
  962. %    o level: Specifies the level in the classification the node resides.
  963. %
  964. %    o mid_red: Specifies the mid point of the red axis for this node.
  965. %
  966. %    o mid_green: Specifies the mid point of the green axis for this node.
  967. %
  968. %    o mid_blue: Specifies the mid point of the blue axis for this node.
  969. %
  970. %
  971. */
  972. static Node *InitializeNode(id,level,parent,mid_red,mid_green,mid_blue)
  973. unsigned int
  974. X  id,
  975. X  level;
  976. X
  977. Node
  978. X  *parent;
  979. X
  980. unsigned int
  981. X  mid_red,
  982. X  mid_green,
  983. X  mid_blue;
  984. {
  985. X  register int
  986. X    i;
  987. X
  988. X  register Node
  989. X    *node;
  990. X
  991. X  if (cube.free_nodes == 0)
  992. X    {
  993. X      register Nodes
  994. X        *nodes;
  995. X
  996. X      /*
  997. X        Allocate a new nodes of nodes.
  998. X      */
  999. X      nodes=(Nodes *) malloc(sizeof(Nodes));
  1000. X      if (nodes == (Nodes *) NULL)
  1001. X        return((Node *) NULL);
  1002. X      nodes->next=cube.node_queue;
  1003. X      cube.node_queue=nodes;
  1004. X      cube.next_node=nodes->nodes;
  1005. X      cube.free_nodes=NodesInAList;
  1006. X    }
  1007. X  cube.nodes++;
  1008. X  cube.free_nodes--;
  1009. X  node=cube.next_node++;
  1010. X  node->parent=parent;
  1011. X  for (i=0; i < 8; i++)
  1012. X    node->child[i]=(Node *) NULL;
  1013. X  node->id=id;
  1014. X  node->level=level;
  1015. X  node->children=0;
  1016. X  node->mid_red=mid_red;
  1017. X  node->mid_green=mid_green;
  1018. X  node->mid_blue=mid_blue;
  1019. X  node->number_colors=0;
  1020. X  node->number_unique=0;
  1021. X  node->total_red=0;
  1022. X  node->total_green=0;
  1023. X  node->total_blue=0;
  1024. X  return(node);
  1025. }
  1026. X
  1027. /*
  1028. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1029. %                                                                             %
  1030. %                                                                             %
  1031. %                                                                             %
  1032. %  P r u n e C h i l d                                                        %
  1033. %                                                                             %
  1034. %                                                                             %
  1035. %                                                                             %
  1036. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1037. %
  1038. %  Function PruneChild deletes the given node and merges its statistics into
  1039. %  its parent.
  1040. %
  1041. %  The format of the PruneSubtree routine is:
  1042. %
  1043. %      PruneChild(node)
  1044. %
  1045. %  A description of each parameter follows.
  1046. %
  1047. %    o node: pointer to node in color cube tree that is to be pruned.
  1048. %
  1049. %
  1050. */
  1051. static void PruneChild(node)
  1052. register Node
  1053. X  *node;
  1054. {
  1055. X  register Node
  1056. X    *parent;
  1057. X
  1058. X  /*
  1059. X    Merge color statistics into parent.
  1060. X  */
  1061. X  parent=node->parent;
  1062. X  parent->children&=~(1 << node->id);
  1063. X  parent->number_unique+=node->number_unique;
  1064. X  parent->total_red+=node->total_red;
  1065. X  parent->total_green+=node->total_green;
  1066. X  parent->total_blue+=node->total_blue;
  1067. X  cube.nodes--;
  1068. }
  1069. X
  1070. /*
  1071. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1072. %                                                                             %
  1073. %                                                                             %
  1074. %                                                                             %
  1075. %  P r u n e L e v e l                                                        %
  1076. %                                                                             %
  1077. %                                                                             %
  1078. %                                                                             %
  1079. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1080. %
  1081. %  Procedure PruneLevel deletes all nodes at the bottom level of the color
  1082. %  tree merging their color statistics into their parent node.
  1083. %
  1084. %  The format of the PruneLevel routine is:
  1085. %
  1086. %      PruneLevel(node)
  1087. %
  1088. %  A description of each parameter follows.
  1089. %
  1090. %    o node: pointer to node in color cube tree that is to be pruned.
  1091. %
  1092. %
  1093. */
  1094. static void PruneLevel(node)
  1095. register Node
  1096. X  *node;
  1097. {
  1098. X  register int
  1099. X    id;
  1100. X
  1101. X  /*
  1102. X    Traverse any children.
  1103. X  */
  1104. X  if (node->children != 0)
  1105. X    for (id=0; id < 8; id++)
  1106. X      if (node->children & (1 << id))
  1107. X        PruneLevel(node->child[id]);
  1108. X  if (node->level == (cube.depth-1))
  1109. X    PruneChild(node);
  1110. }
  1111. X
  1112. /*
  1113. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1114. %                                                                             %
  1115. %                                                                             %
  1116. %                                                                             %
  1117. %  R e d u c e                                                                %
  1118. %                                                                             %
  1119. %                                                                             %
  1120. %                                                                             %
  1121. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1122. %
  1123. %  Function Reduce traverses the color cube tree and prunes any node whose
  1124. %  number of colors fall below a particular threshold.
  1125. %
  1126. %  The format of the Reduce routine is:
  1127. %
  1128. %      Reduce(node)
  1129. %
  1130. %  A description of each parameter follows.
  1131. %
  1132. %    o node: pointer to node in color cube tree that is to be pruned.
  1133. %
  1134. %
  1135. */
  1136. static void Reduce(node)
  1137. register Node
  1138. X  *node;
  1139. {
  1140. X  register unsigned int
  1141. X    id;
  1142. X
  1143. X  /*
  1144. X    Traverse any children.
  1145. X  */
  1146. X  if (node->children != 0)
  1147. X    for (id=0; id < 8; id++)
  1148. X      if (node->children & (1 << id))
  1149. X        Reduce(node->child[id]);
  1150. X  if (node->number_colors <= cube.pruning_threshold)
  1151. X    {
  1152. X      /*
  1153. X        Node has a sub-threshold color count so prune it.  Node is an colormap
  1154. X        entry if parent does not have any unique colors.
  1155. X      */
  1156. X      if (node->parent->number_unique == 0)
  1157. X        cube.colors++;
  1158. X      PruneChild(node);
  1159. X      if (node->parent->number_colors < cube.next_pruning_threshold)
  1160. X        cube.next_pruning_threshold=node->parent->number_colors;
  1161. X    }
  1162. X  else
  1163. X    {
  1164. X      /*
  1165. X        Find minimum pruning threshold.  Node is a colormap entry if it has
  1166. X        unique colors.
  1167. X      */
  1168. X      if (node->number_unique > 0)
  1169. X        cube.colors++;
  1170. X      if (node->number_colors < cube.next_pruning_threshold)
  1171. X        cube.next_pruning_threshold=node->number_colors;
  1172. X    }
  1173. }
  1174. X
  1175. /*
  1176. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1177. %                                                                             %
  1178. %                                                                             %
  1179. %                                                                             %
  1180. %  R e d u c t i o n                                                          %
  1181. %                                                                             %
  1182. %                                                                             %
  1183. %                                                                             %
  1184. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1185. %
  1186. %  Function Reduction repeatedly prunes the tree until the number of nodes
  1187. %  with n2 > 0 is less than or equal to the maximum number of colors allowed
  1188. %  in the output image.  On any given iteration over the tree, it selects
  1189. %  those nodes whose n1  count is minimal for pruning and merges their
  1190. %  color statistics upward. It uses a pruning threshold, ns, to govern
  1191. %  node selection as follows:
  1192. %
  1193. %    ns = 0
  1194. %    while number of nodes with (n2 > 0) > required maximum number of colors
  1195. %      prune all nodes such that n1 <= ns
  1196. %      Set ns to minimum n1 in remaining nodes
  1197. %
  1198. %  When a node to be pruned has offspring, the pruning procedure invokes
  1199. %  itself recursively in order to prune the tree from the leaves upward.
  1200. %  n2,  Sr, Sg,  and  Sb in a node being pruned are always added to the
  1201. %  corresponding data in that node's parent.  This retains the pruned
  1202. %  node's color characteristics for later averaging.
  1203. %
  1204. %  For each node, n2 pixels exist for which that node represents the
  1205. %  smallest volume in RGB space containing those pixel's colors.  When n2
  1206. %  > 0 the node will uniquely define a color in the output image. At the
  1207. %  beginning of reduction,  n2 = 0  for all nodes except a the leaves of
  1208. %  the tree which represent colors present in the input image.
  1209. %
  1210. %  The other pixel count, n1, indicates the total number of colors
  1211. %  within the cubic volume which the node represents.  This includes n1 -
  1212. %  n2  pixels whose colors should be defined by nodes at a lower level in
  1213. %  the tree.
  1214. %
  1215. %  The format of the Reduction routine is:
  1216. %
  1217. %      Reduction(number_colors)
  1218. %
  1219. %  A description of each parameter follows.
  1220. %
  1221. %    o number_colors: This integer value indicates the maximum number of
  1222. %      colors in the quantized image or colormap.  The actual number of
  1223. %      colors allocated to the colormap may be less than this value, but
  1224. %      never more.  Note, the number of colors is restricted to a value
  1225. %      less than or equal to 65536 if the continuous_tone parameter has a
  1226. %      value of zero.
  1227. %
  1228. %
  1229. */
  1230. static void Reduction(number_colors)
  1231. unsigned int
  1232. X  number_colors;
  1233. {
  1234. X  cube.next_pruning_threshold=1;
  1235. X  while (cube.colors > number_colors)
  1236. X  {
  1237. X    cube.pruning_threshold=cube.next_pruning_threshold;
  1238. X    cube.next_pruning_threshold=cube.root->number_colors-1;
  1239. X    cube.colors=0;
  1240. X    Reduce(cube.root);
  1241. X  }
  1242. }
  1243. X
  1244. /*
  1245. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1246. %                                                                             %
  1247. %                                                                             %
  1248. %                                                                             %
  1249. %  Q u a n t i z a t i o n E r r o r                                          %
  1250. %                                                                             %
  1251. %                                                                             %
  1252. %                                                                             %
  1253. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1254. %
  1255. %  Function QuantizationError measures the difference between the original
  1256. %  and quantized images.  This difference is the total quantization error.
  1257. %  The error is computed by summing over all pixels in an image the distance
  1258. %  squared in RGB space between each reference pixel value and its quantized
  1259. %  value.
  1260. %
  1261. %  The format of the QuantizationError routine is:
  1262. %
  1263. %      QuantizationError(image,mean_error_per_pixel,
  1264. %        normalized_mean_square_error,normalized_maximum_square_error)
  1265. %
  1266. %  A description of each parameter follows.
  1267. %
  1268. %    o image: The address of a byte (8 bits) array of run-length
  1269. %      encoded pixel data of your reference image.  The sum of the
  1270. %      run-length counts in the reference image must be equal to or exceed
  1271. %      the number of pixels.
  1272. %
  1273. %    o mean_error_per_pixel: The address of an integer value.  The value
  1274. %      returned is the mean error for any single pixel in the image.
  1275. %
  1276. %    o normalized_mean_square_error: The address of a real value.  The value
  1277. %      returned is the normalized mean quantization error for any single
  1278. %      pixel in the image.  This distance measure is normalized to a
  1279. %      range between 0 and 1.  It is independent of the range of red,
  1280. %      green, and blue values in your image.
  1281. %
  1282. %    o normalized_maximum_square_error: The address of a real value.  The value
  1283. %      returned is the normalized maximum quantization error for any
  1284. %      single pixel in the image.  This distance measure is normalized to
  1285. %      a range between 0 and 1.  It is independent of the range of red,
  1286. %      green, and blue values in your image.
  1287. %
  1288. %
  1289. */
  1290. void QuantizationError(image,mean_error_per_pixel,normalized_mean_square_error,
  1291. X  normalized_maximum_square_error)
  1292. Image
  1293. X  *image;
  1294. X
  1295. unsigned int
  1296. X  *mean_error_per_pixel;
  1297. X
  1298. double
  1299. X  *normalized_mean_square_error,
  1300. X  *normalized_maximum_square_error;
  1301. {
  1302. X  register int
  1303. X    i;
  1304. X
  1305. X  register RunlengthPacket
  1306. X    *p;
  1307. X
  1308. X  register unsigned int
  1309. X    blue_distance,
  1310. X    green_distance,
  1311. X    red_distance;
  1312. X
  1313. X  unsigned long
  1314. X    distance,
  1315. X    maximum_error_per_pixel,
  1316. X    total_error;
  1317. X
  1318. X  /*
  1319. X    For each pixel, collect error statistics.
  1320. X  */
  1321. X  for (i=(-MaxRGB); i <= MaxRGB; i++)
  1322. X    cube.squares[i+MaxRGB]=i*i;
  1323. X  maximum_error_per_pixel=0;
  1324. X  total_error=0;
  1325. X  p=image->pixels;
  1326. X  for (i=0; i < image->packets; i++)
  1327. X  {
  1328. X    red_distance=(int) p->red-(int) image->colormap[p->index].red+MaxRGB;
  1329. X    green_distance=(int) p->green-(int) image->colormap[p->index].green+MaxRGB;
  1330. X    blue_distance=(int) p->blue-(int) image->colormap[p->index].blue+MaxRGB;
  1331. X    distance=cube.squares[red_distance]+cube.squares[green_distance]+
  1332. X      cube.squares[blue_distance];
  1333. X    total_error+=(distance*(p->length+1));
  1334. X    if (distance > maximum_error_per_pixel)
  1335. X      maximum_error_per_pixel=distance;
  1336. X    p++;
  1337. X  }
  1338. X  /*
  1339. X    Compute final error statistics.
  1340. X  */
  1341. X  *mean_error_per_pixel=(unsigned int) total_error/(image->columns*image->rows);
  1342. X  *normalized_mean_square_error=((double) *mean_error_per_pixel)/
  1343. X    (3.0*(MaxRGB+1)*(MaxRGB+1));
  1344. X  *normalized_maximum_square_error=((double) maximum_error_per_pixel)/
  1345. X    (3.0*(MaxRGB+1)*(MaxRGB+1));
  1346. }
  1347. X
  1348. /*
  1349. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1350. %                                                                             %
  1351. %                                                                             %
  1352. %                                                                             %
  1353. %  Q u a n t i z e I m a g e                                                  %
  1354. %                                                                             %
  1355. %                                                                             %
  1356. %                                                                             %
  1357. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1358. %
  1359. %  Function QuantizeImage analyzes the colors within a reference image and
  1360. %  chooses a fixed number of colors to represent the image.  The goal of the
  1361. %  algorithm is to minimize the difference between the input and output image
  1362. %  while minimizing the processing time.
  1363. %
  1364. %  The format of the QuantizeImage routine is:
  1365. %
  1366. %      colors=QuantizeImage(image,number_colors,tree_depth,dither,optimal)
  1367. %
  1368. %  A description of each parameter follows.
  1369. %
  1370. %    o colors: The QuantizeImage function returns this integer
  1371. %      value.  It is the actual number of colors allocated in the
  1372. %      colormap.  Note, the actual number of colors allocated may be less
  1373. %      than the number of colors requested, but never more.
  1374. %
  1375. %    o image: Specifies a pointer to an Image structure;  returned from
  1376. %      ReadImage.
  1377. %
  1378. %    o number_colors: This integer value indicates the maximum number of
  1379. %      colors in the quantized image or colormap.  The actual number of
  1380. %      colors allocated to the colormap may be less than this value, but
  1381. %      never more.  Note, the number of colors is restricted to a value
  1382. %      less than or equal to 65536 if the continuous_tone parameter has a
  1383. %      value of zero.
  1384. %
  1385. %    o tree_depth: Normally, this integer value is zero or one.  A zero or
  1386. %      one tells Quantize to choose a optimal tree depth of Log4(number_colors).
  1387. %      A tree of this depth generally allows the best representation of the
  1388. %      reference image with the least amount of memory and the fastest
  1389. %      computational speed.  In some cases, such as an image with low color
  1390. %      dispersion (a few number of colors), a value other than
  1391. %      Log4(number_colors) is required.  To expand the color tree completely,
  1392. %      use a value of 8.
  1393. %
  1394. %    o dither: Set this integer value to something other than zero to
  1395. %      dither the quantized image.  The basic strategy of dithering is to
  1396. %      trade intensity resolution for spatial resolution by averaging the
  1397. %      intensities of several neighboring pixels.  Images which suffer
  1398. %      from severe contouring when quantized can be improved with the
  1399. %      technique of dithering.  Severe contouring generally occurs when
  1400. %      quantizing to very few colors, or to a poorly-chosen colormap.
  1401. %      Note, dithering is a computationally expensive process and will
  1402. %      increase processing time significantly.
  1403. %
  1404. %    o colorspace: An unsigned integer value that indicates the colorspace.
  1405. %      Empirical evidence suggests that distances in YUV or YIQ correspond to
  1406. %      perceptual color differences more closely than do distances in RGB
  1407. %      space.  The image is then returned to RGB colorspace after color
  1408. %      reduction.
  1409. %
  1410. %    o optimal: An unsigned integer value greater than zero indicates that
  1411. %      the optimal representation of the reference image should be returned.
  1412. %
  1413. %
  1414. */
  1415. void QuantizeImage(image,number_colors,tree_depth,dither,colorspace,optimal)
  1416. Image
  1417. X  *image;
  1418. X
  1419. unsigned int
  1420. X  number_colors,
  1421. X  tree_depth,
  1422. X  dither,
  1423. X  colorspace,
  1424. X  optimal;
  1425. {
  1426. X  Nodes
  1427. X    *nodes;
  1428. X
  1429. X  /*
  1430. X    Reduce the number of colors in the continuous tone image.
  1431. X  */
  1432. X  if (number_colors > MaxColormapSize)
  1433. X    number_colors=MaxColormapSize;
  1434. X  InitializeCube(number_colors,tree_depth,image->columns*image->rows,optimal);
  1435. X  dither|=!optimal;
  1436. X  if (!dither)
  1437. X    if (image->packets == (image->columns*image->rows))
  1438. X      CompressImage(image);
  1439. X  if (colorspace != RGBColorspace)
  1440. X    RGBTransformImage(image,colorspace);
  1441. X  Classification(image);
  1442. X  Reduction(number_colors);
  1443. X  Assignment(image,dither,colorspace,optimal);
  1444. X  if (colorspace != RGBColorspace)
  1445. X    TransformRGBImage(image,colorspace);
  1446. X  /*
  1447. X    Release color cube tree storage.
  1448. X  */
  1449. X  do
  1450. X  {
  1451. X    nodes=cube.node_queue->next;
  1452. X    (void) free((char *) cube.node_queue);
  1453. X    cube.node_queue=nodes;
  1454. X  }
  1455. X  while (cube.node_queue != (Nodes *) NULL);
  1456. }
  1457. X
  1458. /*
  1459. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1460. %                                                                             %
  1461. %                                                                             %
  1462. %                                                                             %
  1463. %   Q u a n t i z e I m a g e s                                               %
  1464. %                                                                             %
  1465. %                                                                             %
  1466. %                                                                             %
  1467. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1468. %
  1469. %  QuantizeImages analyzes the colors within a set of reference images and
  1470. %  chooses a fixed number of colors to represent the set.  The goal of the
  1471. %  algorithm is to minimize the difference between the input and output images
  1472. %  while minimizing the processing time.
  1473. %
  1474. %  The format of the QuantizeImages routine is:
  1475. %
  1476. %      QuantizeImages(images,number_images,number_colors,tree_depth,dither,
  1477. %        optimal)
  1478. %
  1479. %  A description of each parameter follows:
  1480. %
  1481. %    o images: Specifies a pointer to a set of Image structures.
  1482. %
  1483. %    o number_images:  Specifies an unsigned integer representing the number
  1484. %      images in the image set.
  1485. %
  1486. %    o colormap_image: Specifies a pointer to a Image structure.  Reduce
  1487. %      images to a set of colors represented by this image.
  1488. %
  1489. %    o number_colors: This integer value indicates the maximum number of
  1490. %      colors in the quantized image or colormap.  The actual number of colors
  1491. %      allocated to the colormap may be less than this value, but never more.
  1492. %      Note, the number of colors is restricted to a value less than or equal
  1493. %      to 65536 if the quantized image is not DirectClass.
  1494. %
  1495. %    o tree_depth: Normally, this integer value is zero or one.  A zero or
  1496. %      one tells QUANTIZE to choose a optimal tree depth.  An optimal depth
  1497. %      generally allows the best representation of the reference image with the
  1498. %      fastest computational speed and the least amount of memory.  However,
  1499. %      the default depth is inappropriate for some images.  To assure the best
  1500. %      representation, try values between 2 and 8 for this parameter.
  1501. %
  1502. %    o dither: Set this integer value to something other than zero to
  1503. %      dither the quantized image.  The basic strategy of dithering is to
  1504. %      trade intensity resolution for spatial resolution by averaging the
  1505. %      intensities of several neighboring pixels.  Images which suffer
  1506. %      from severe contouring when quantized can be improved with the
  1507. %      technique of dithering.  Severe contouring generally occurs when
  1508. %      quantizing to very few colors, or to a poorly-chosen colormap.
  1509. %      Note, dithering is a computationally expensive process and will
  1510. %      increase processing time significantly.
  1511. %
  1512. %    o colorspace: An unsigned integer value that indicates the colorspace.
  1513. %      Empirical evidence suggests that distances in YUV or YIQ correspond to
  1514. %      perceptual color differences more closely than do distances in RGB
  1515. %      space.  The image is then returned to RGB colorspace after color
  1516. %      reduction.
  1517. %
  1518. %    o optimal: An unsigned integer value greater than zero indicates that
  1519. %      the optimal representation of the reference image should be returned.
  1520. %
  1521. %
  1522. */
  1523. void QuantizeImages(images,number_images,colormap_image,number_colors,
  1524. X  tree_depth,dither,colorspace,optimal)
  1525. Image
  1526. X  **images;
  1527. X
  1528. unsigned int
  1529. X  number_images;
  1530. X
  1531. Image
  1532. X  *colormap_image;
  1533. X
  1534. unsigned int
  1535. X  number_colors,
  1536. X  tree_depth,
  1537. X  dither,
  1538. X  colorspace,
  1539. X  optimal;
  1540. {
  1541. X  Nodes
  1542. X    *nodes;
  1543. X
  1544. X  register unsigned int
  1545. X    i;
  1546. X
  1547. X  /*
  1548. X    Reduce the number of colors in the continuous tone image sequence.
  1549. X  */
  1550. X  InitializeCube(number_colors,tree_depth,~0,optimal);
  1551. X  dither|=!optimal;
  1552. X  if (colormap_image != (Image *) NULL)
  1553. X    {
  1554. X      /*
  1555. X        Reduce images to a set of colors represented by the colormap image.
  1556. X      */
  1557. X      if (!dither)
  1558. X        if (colormap_image->packets ==
  1559. X             (colormap_image->columns*colormap_image->rows))
  1560. X          CompressImage(colormap_image);
  1561. X      if (colorspace != RGBColorspace)
  1562. X        RGBTransformImage(colormap_image,colorspace);
  1563. SHAR_EOF
  1564. true || echo 'restore of ImageMagick/quantize.c failed'
  1565. fi
  1566. echo 'End of ImageMagick part 30'
  1567. echo 'File ImageMagick/quantize.c is continued in part 31'
  1568. echo 31 > _shar_seq_.tmp
  1569. exit 0
  1570.  
  1571. exit 0 # Just in case...
  1572. -- 
  1573.   // chris@Sterling.COM           | Send comp.sources.x submissions to:
  1574. \X/  Amiga - The only way to fly! |    sources-x@sterling.com
  1575.  "It's intuitively obvious to the |
  1576.   most casual observer..."        | GCS d+/-- p+ c++ l+ m+ s++/+ g+ w+ t+ r+ x+
  1577.