home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #19 / NN_1992_19.iso / spool / comp / compress / 3145 < prev    next >
Encoding:
Internet Message Format  |  1992-08-31  |  5.7 KB

  1. Xref: sparky comp.compression:3145 alt.graphics.pixutils:2076 sci.image.processing:589
  2. Newsgroups: comp.compression,alt.graphics.pixutils,sci.image.processing
  3. Path: sparky!uunet!zaphod.mps.ohio-state.edu!cs.utexas.edu!torn!watserv2.uwaterloo.ca!watmath!watcgl!watpix.uwaterloo.ca!awpaeth
  4. From: awpaeth@watpix.uwaterloo.ca (Alan Wm Paeth)
  5. Subject: Lossless (Re: Best) compression for 24 bit images
  6. Message-ID: <BtvC99.Ir5@watcgl.uwaterloo.ca>
  7. Sender: news@watcgl.uwaterloo.ca (USENET News System)
  8. Organization: University of Waterloo
  9. References: <1992Aug28.133552.16085@crd.ge.com> <1685110E1C.IRHANV00@UKCC.UKY.EDU>
  10. Date: Mon, 31 Aug 1992 22:10:20 GMT
  11. Lines: 132
  12.  
  13. >In article <1992Aug28.133552.16085@crd.ge.com>
  14. >davidsen@ariel.crd.GE.COM (william E Davidsen) writes:
  15. What is the best way to do lossless compression of 24 bit images?
  16.  
  17. A lossless technique accommodating arbitrary precision without the use of
  18. tables is described in Graphics Gems II. The method "whitens" 2D images so that
  19. their sequential 1D raster representations are more amenable to compression by
  20. tools such as Unix Compress or MSDOS ZIP.  It is intentionally nonadaptive, as
  21. that work is left to the conventional (1D) coder which follows downstream. The
  22. method is based on predictive-corrective methods and may be regarded as an
  23. extension to the "use the pixel 'above' on the previous scanline" technique.
  24.  
  25. In a nutshell, given a raster presented in standard CRT-scan order then the
  26. pixel in question (*) has three adjacent neighbors, a, b and c which have
  27. already been seen:
  28.  
  29.  
  30.      a  b
  31.      
  32.      c (*).
  33.      
  34. A trial prediction employs Robert's gradient finder to estimate the slope of
  35. the NW/SE diagonal:
  36.  
  37.     slope = b + c - 2a
  38.  
  39. and adds this to the pixel at "a":
  40.  
  41.     trial = b + c - a 
  42.  
  43. which forms an exact estimate should all four pixels lie on a planar "wedge"
  44. of intensity (linear slope in two dimensions).
  45.  
  46. The "twist" is the non-linear final step forming an estimate by selecting that
  47. pixel from the trial set {a, b, c} having a value closest (ie, which minimizes
  48. the absolute value) to the trial prediction. Since two pixels of dissimilar
  49. value may be the closest to the trial estimate (ie, equidistant), a tie-break
  50. order is required. It is a, b, c. The code for the last step resembles:
  51.  
  52.    if |trial - a| < |trial - b| and |trial - a| < |trial - c| return(a)
  53.    if |trial - b| < |trial - c| return(b)
  54.    return(c)
  55.  
  56. (The Gem pseudocode is more concise; the concluding C-code more efficient).
  57.  
  58. The motivation in terms of symmetry of design is treated at length in the text;
  59. this non-linear step yields a number of benefits. Among them, it allows the
  60. algorithm to hold up well when presented 1-bit data -- the final estimate is
  61. never fractional. The estimates also match the "best" choices predicted by
  62. empirical analysis of 1-bit data. The method also supports a fast encoding
  63. given arbitrary precision, in much the same way that Median filtering of input
  64. does. (BTW, Median filtering and many varients was also studied in the course
  65. of deriving this filter; it could not be made to work as well). Also, forming a
  66. final choice from the input seen guarentees the estimate lies within the right
  67. domain. This means that any pixel-wise "range clipping" of the estimate (ie,
  68. when negative) step may be removed from the inner loop of the algorithm. More
  69. important, if the "colours" presented to the coder are "sparse" (e.g., only a
  70. few levels occuring in any subregion, despite 24-bit precision), the coder
  71. correctly locates estimates from within the "sparse" set, unlike most other
  72. techniques. This is a further win should the filter encounter synthetically
  73. rendered images.
  74.  
  75. Lest I steal my own thunder, the Gems article also describes requirements of
  76. a suitable non-adaptive 2D coder and derives the algorithm from this. The
  77. entry also includes empirical data, histograms and sample images, plus some
  78. pseudocode, which models the simple equations listed above.
  79.  
  80. For those who enjoy hacking inner loops of image processing tools, the fastest
  81. implementation I've been able to create is for use with Waterloo's IM Raster
  82. Toolkit. (In fact, the method was invented with this code suite in mind: a
  83. lossless method for use with composable Unix-based tools accommodating
  84. arbitrary bit precision). I've minimized the number of variables employed to
  85. allow use of the C-language "register" compiler directive for further
  86. optimization given integer pixels of arbitrary precision. The variables and
  87. then the code snipped follow the signature.
  88.  
  89.    /Alan Paeth VE3AWP/KD3XG
  90.    Computer Graphics Laboratory,
  91.    University of Waterloo
  92.  
  93.  
  94. Prefacing Notes:
  95.  
  96. b1  -- a pointer to the previous scanline of (integer) input values
  97. b2  -- a pointer to the current  "    "
  98. ob  -- a pointer to the output scanline of identical precision
  99.  t  -- temporary variable
  100. col -- number of pixels in scanline arrays b1, b2 and ob
  101.  g  -- estimated gradient
  102. d1  -- trial distances to pixel a
  103. d2  -- trial distances to pixel b
  104. d3  -- trial distances to pixel c
  105.  
  106.  p  -- the current pixel (relates to the "correction" step)
  107. mask-- a bit-use mask (relates to reuse of the tool for "decoding" of data)
  108.  
  109. -----
  110. ...
  111.  
  112. /*
  113.  * We consider (implicitly) the equations:
  114.  *
  115.  * g  = (b+c-a) = Roberts' gradient
  116.  * d1 = |g - a| = |b+c-2a|
  117.  * d2 = |g - b| = |c-a|
  118.  * d3 = |g - c| = |b-a|
  119.  *
  120.  * then pick the smallest of d1,d2,d3 in that order.
  121.  */
  122.         while(--col>=0)
  123.         {
  124.         a = *b1++;
  125.         c = *b2++;        /* for "b" use "*b1" */
  126.         if ((m = *b1 + c - a - a) < 0) m = -m;    /* m = |b+c-2a| */
  127.         p = a;
  128.         if ((t = a - c) < 0) t = -t;        /* t = |a-c| */
  129.         if (t < m)
  130.             {
  131.             m = t;
  132.             p = *b1;
  133.             }
  134.         if ((t = *b1 - a) < 0) t = -t;        /* t = |b-a| */
  135.         if (t < m) p = c;
  136.         *ob++ = (p - *ib++) & mask;
  137.         }
  138.         }
  139.     writeline();
  140.     }
  141.     imclose();
  142.     exit(0);
  143.     }
  144.