Netpbm
The portable pixmap file format (PPM), the portable graymap file format (PGM), the portable bitmap file format (PBM), the portable floatmap file format (PFM) and the portable anymap file format (PAM) specify rules for exchanging graphics files. They provide very basic functionality and serve as a least-common-denominator for converting between different platforms. Several applications refer to them collectively as the PNM format (portable anymap).
Netpbm usage
The Netpbm package can, for example, use two successive conversion programs to turn this code into a bmp file:
pgmtoppm "#FFFFFF" j.pbm > j.ppm ppmtobmp j.ppm > j.bmp
Depending on the identification of the file format, portable pixmap systems can distinguish three similar file formats, each with two versions:
- PBM - portable bitmap file format (P1/P4) - 1 bit per pixel
- PGM - portable graymap file format (P2/P5) - 8 bits per pixel
- PPM - portable pixmap file format (P3/P6) - 24 bits per pixel, 8 for red, 8 for green, 8 for blue
- PAM - portable anymap file format (P7) - all of the above plus more.
In each case, the lower-numbered version (P1, P2 or P3) refers to a human-readable, ASCII-based format similar to the one in the example above; and the higher-numbered version (P4, P5, P6 or P7) refers to a binary format.
File format description
PBM example
Take the example of the letter "J" as a bitmap:
....X. ....X. ....X. ....X. ....X. ....X. X...X. .XXX.. ...... ......
The most basic (monochrome) PBM format represents it as follows:
P1 # This is an example bit map file j.pbm 6 10 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 1 0 0 0 1 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0
The string P1 identifies the file format. The hash sign introduces a comment. The next two numbers give the width and the height. Then follows the matrix with the pixel values (in the monochrome case here, only zeros and ones).
The PGM and PPM formats (both ASCII and binary versions) have an additional parameter for the maximum value in a line between the X and Y dimensions and the actual pixel data.
PPM example
P3 #the P3 means colors are in ascii, then 3 columns and 2 rows, then 255 for max color, then RGB triplets 3 2 255 255 0 0 0 255 0 0 0 255 255 255 0 255 255 255 0 0 0
The P6 format of the same image will store a color with one byte. The file will be smaller but the color information will not be readable by humans:
P6 #any comment string 3 2 255 !@#$%^&*()_+|{}:"<
The PPM format is not compressed. The PPM format is certainly simple to write from scratch. The following Python code makes the above example image. It can be adapted to making useful images by reading or constructing an array of numerical data, and progamming a conversion of the data to color triplets.
#!/usr/bin/python triplets=[ [255, 0, 0], [0, 255, 0], [0, 0, 255], [255, 255, 0], [255, 255, 255], [0, 0, 0] ] width=3 height=2 comment='any comment string' ftype='P6' #use 'P3' for ascii, 'P6' for binary ppmfile=open('testimage.ppm','wb') ppmfile.write("%s\n" % (ftype)) ppmfile.write("#%s\n" % comment ) ppmfile.write("%d %d\n" % (width, height)) ppmfile.write("255\n") if ftype=='P3': for red,green,blue in triplets: ppmfile.write("%d %d %d\n" % (red,green,blue)) elif ftype=='P6': #print 1 byte per color for red,green,blue in triplets: ppmfile.write("%c%c%c" % (red,green,blue)) ppmfile.close()
PAM
The PAM graphics format generalises all the features of the previous formats (PBM, PGM and PPM) and provides for extending them. As well as width, height and maximum value, which are found in the older formats, PAM defines two new attributes: depth and tuple type.
The depth attribute defines the number of channels in the image, such as 1 for greyscale images and 3 for RGB images. The tuple type attribute specifies what kind of image the PAM file represents, thus enabling it to stand for the older Netpbm formats, as well as to be extended to new uses. For example, an image with a tuple type of GRAYSCALE is equivalent to PGM (portable graymap).
Fundamental differences from the older formats
The header for the PAM file format begins with P7, and (unlike in the other formats) ends in an explicit close: ENDHDR.
There is no plain (human-readable, ASCII-based) version of PAM. P
For the black-and-white version of PAM (depth 1, tuple type BLACKANDWHITE), corresponding to PBM, PAM uses one byte per pixel, instead of PBM’s use of one bit per pixel (packing eight pixels in one byte). Also, the value 1 in such a PAM image stands for white (“light on”), as opposed to black in PBM (“ink on”).
Extended uses
Extensions that include an opacity channel exist: for example tuple type RGB_ALPHA (with depth 4) serves for RGBA images, which previously required the use of a separate PGM image for the opacity channel. In theory, PAM can be extended to represent colour models like CMYK, and even non-graphical information arrays.
16-bit extensions
The original definition of the PGM and the PPM binary formats (the P5 and P6 formats) did not allow bit depths greater than 8 bits. One can of course use the ASCII format, but this format both slows down reading and makes the files much larger. Accordingly, many programmers have attempted to extend the format to allow higher bit depths. Using higher bit depths encounters the problem of having to decide on the endianness of the file. Unfortunately it appears that the various implementations could not agree on which byte order to use; Netpbm, the de facto standard implementation of the PNM formats, uses big-endian.