PNG and TIFF Predictors Filter

From GNUpdf

Predictor filters are specified in the filter options of FlateDec and LZWDec filters.

Contents

TIFF

TIFF: Tiff Predictor 2 function in the Tiff standard (section 14, Horizontal Differencing):

Make use of the fact that many continuous-tone images rarely vary much in pixel value from one pixel to the next. In such images, 
if we replace the pixel values by differences between consecutive pixels, many of the differences should be 0, plus or minus 1, and 
so on. This reduces the  apparent information content and allows LZW to encode the data more compactly.

Assuming 8-bit grayscale pixels for the moment, a basic C implementation might look something like this:

 char image[][];
 int row,col;

 /* Take horizontal differences: */
 for (row = 0; row < nrows; row++)
 {
  for (col = ncols - 1; col >= 1; col--)
   {
    image[row][col] -= image[row][col - 1];
   }
 }

If we don't have 8-bit components, we need to work a little harder to make better use of the architecture of most CPUs. Suppose 
we have 4-bit components packed two per byte in the normal TIFF uncompressed (i.e., Compression = 1) fashion. To find differences, 
we want to first expand each 4-bit component into an 8-bit bytes, so that we have one component per byte, low-order justified. We then 
perform the horizontal differencing illustrated in the example above. Once the differencing has been completed, we then repack the 
4-bit differences two to a byte, in the normal TIFF uncompressed fashion.

If the components are greater than 8 bits deep, expanding the components into 16-bit words instead of 8-bit bytes seems like the 
best way to perform the subtraction on most computers.

Note that we have not lost any data up to this point, nor will we lose any data later on. It might seem at first that our differencing 
might turn 8-bit components into 9-bit differences, 4-bit components into 5-bit differences, and so on. But it turns out that we can 
completely ignore the  "overflow" bits caused by substracting a larger number from a smaller number and still reverse the process 
without error. Normal two's complement arithmetic does just what we want. Try an example by hand if you need more convincing.

Up to this point we have implicitly assumed that we are compressing bilevel or grayscale images. An additional consideration arises in 
the case of color images.

If PlanarConfiguration is 2, there is no problem. Differencing works the same as it does for garyscale data.

If PlanarConfiguration is 1, however, things get a little tricker. If we didn't do anything special, we would substract red 
component values form green component values, green component values from blue component values, and blue component values values 
from red component values. This would not give the LZW coding stage much redundancy to work with. So, we will do our horizontal 
differences with an offset of SamplesPerPixel (3, in the RGB case). In other words, we will subtract red from red, green from green, 
and blue from blue. The LZW coding stage is identical to the SamplesPerPixel=1 case. We require that BitsPerSample be the same for 
all 3 components.

PNG

Filter type 1: Sub

  • Pre-compression: Subx = RawxRawxbpp
  • Post-decompression: Rawx = Subx + Rawxbpp

Notes:

  • For all x < 0, assume Rawx = 0
  • Computation unsigned mod 256.

Filter type 2: Up

  • Pre-compression: Upx = RawxPriorx
  • Post-decompression: Rawx = Upx + Priorx

Notes:

  • On the first scanline of the image, assume Priorx = 0 for all x.
  • Computation unsigned mod 256.

Filter type 3: Average

  • Pre-compression: Averagex = Rawxfloor((Rawxbpp + Priorx) / 2)
  • Post-decompression: Rawx = Averagex + floor((Rawxbpp + Priorx) / 2)

Notes:

  • For all x < 0, assume Rawx = 0
  • On the first scanline of the image, assume Priorx = 0 for all x.
  • Computation unsigned mod 256.

Filter type 4: Paeth

Paeth predictor function:

 function PaethPredictor (a, b, c)
 begin
   ; a = left, b = above, c = upper left
   p := a + b - c        ; initial estimate
   pa := abs(p - a)      ; distances to a, b, c
   pb := abs(p - b)
   pc := abs(p - c)
   ; return nearest of a,b,c,
   ; breaking ties in order a,b,c.
   if pa <= pb AND pa <= pc then return a
   else if pb <= pc then return b
          else return c
 end
  • Pre-compression: Paethx = RawxPaethPredictor(Rawxbpp,Priorx,Priorxbpp)
  • Post-compression:Rawx = Paethx + PaethPredictor(Rawxbpp,Priorx,Priorxbpp)

Notes:

  • The calculations within the Paeth function must be performed exactly, without overflow. Arithmetic modulo 256 is to be used only for the final step of substracting the function result from the target byte value.
  • For all x < 0, assume Rawx = 0 and Priorx = 0. On the first scanline of an image (or of a pass of an interlaced image), assume Priorx = 0 for all x.