prf (polychrome recursive format) is a image file format. It is an extension of mrf (monochrome recursive format), created by Russell Marks, author of zgv. mrf, as the name suggests, applies only to monochrome images. It is an elegant and effective format, reducing image files to sizes not much larger than png, but using much less code. prf is my personal attempt to apply the same idea behind mrf to grayscale/color images. It is not nearly as effective at reducing file sizes, and the code is a little bit less simple. But it may yet have its uses. If nothing else, it's a good compromise for a programming task that needs images stored more compactly than pnm but can't afford a full-scale png implementation.
This distribution includes programs to translate between pnm and prf. The code is relatively straightforward, and acts as a "reference version" for anyone wishing to experiment with prf.
The programs in this distribution are written by Brian Raiter, January 2001, and have been placed in the public domain. Contact me if you have any questions or comments.
Here is a brief description of the prf file format (taken from the prf(5) man page included in the distribution).
A prf file begins with the following header:
Offset Description 0 magic number - "PRF1" (in ASCII) 4 width (32-bit, MSB first) 8 height (same) 12 number of bits per pixel, less one (max. of 31) 13 image data
The image data, begining at the 13th byte and continuing to the end of the file, is a bitstream. Like the header data, multibit values are always stored big-endian.
As with mrf, the image is treated as a number of 64x64 squares, forming a grid large enough to completely cover it. Each of these squares in turn (in left-to-right, top-to-bottom order) can be recursively subdivided into four sub-squares, all the way down to individual pixels.
When a square is being encoded, its pixels are checked to see if they have one or more upper (i.e., most significant) bits in common. If they do, these common bits are output before recursing, and are then ignored when testing for further common bits in the sub-squares. Recursion bottoms out when all the pixels in a square are the same color (which might not happen until the square is a single pixel).
The following pseudocode gives a rough outline of the recursive procedure. When the procedure is first called, the square size equals 64x64, and N equals the number of bits per pixel.
- If square size equals 1x1, output the N lowest bits of the pixel and return.
- Count the number of upper bits shared by all pixels in the square.
- Output this count, followed by the common bits (if any).
- Subtract this count from N.
- If N is zero, return.
- Divide the square into four quarters, calling routine for each in this order: top-left, top-right, bottom-left, bottom-right.
There are two details omitted in the above pseudocode.
The first is the number of bits used to output the count of common bits. This number is always the smallest number of bits needed to encode N + 1 values (i.e., the range 0..N inclusive). For example, when N equals 8, the count can range from 0 to 8, so four bits will be used. If N drops to 7, then no more than three bits will be used subsequently.
The second detail concerns the right-most and bottom-most squares of the image. Unless the image's dimensions are exactly divisible by 64, some squares may be entirely outside the region of the image. These squares are omitted from the bitstream. (Squares that lie partially inside and partially outside the image are encoded normally. Pixels inside these squares but outside the image are indeterminate, and the encoding program can treat them as having whatever values provide the best compression.)
Color images are essentially treated by prf as three interleaved grayscale images. Each color plane is separately encoded in the manner described by the above pseudocode. In the file, the planes are broken up into rows, each row being 64 pixels high, and the rows are then interleaved in the order red, blue, green. (An alpha channel can also appear as the fourth plane.) Thus, immediately following the upper-right square for the red plane would be the upper-left square for the green plane, and so on.
Color images are indicated in the header by storing the number of planes, less one, in the upper three bits of the byte at offset 12.