Reads a psuedo-PNM image as input. Performs gamma correction, and produces a PNM image as output.
Alternatively, this program can undo gamma correction.
The PPM specification states that the sample values in the image are nonlinear, i.e. not directly proportional to light intensity, i.e. gamma corrected. But there exist images that are PPM in every respect except that their sample values are directly proportional to light intensity. People may loosely refer to these as PPM, but they are not. pnmgamma converts these pseudo-PPM images to true PPM by performing gamma correction. To get true PPM, you must specify the -cieramp option and no gamma values. That causes pnmgamma to apply the CIE Rec. 709 gamma transfer function, as specified by the PPM format specification.
On the other hand, you can use the -ungamma option to convert from true PPM to linear RGB pseudo-PPM. (Again, if the input is true PPM, specify the -cieramp option and no gamma values).
The situation for PGM images is analogous. And pnmgamma treats PBM images as PGM images.
You can also apply a different transfer function (which means you don't end up with a true PPM image) by selecting the gamma values as arguments or omitting the -cieramp option. The gamma value is the power to which the input value is raised in the transfer function. A value of 1 means the output is the same as the input. A value less than one makes the output samples numerically less than the input samples; A value greater than one makes the samples numerically greater.
Without the -cieramp option, the transfer function is a simple power function. With -cieramp, it is a power function modified with a linear ramp near black, as described in CIE Rec. 709.
A good explanation of gamma is in Charles Poynton's GammaFAQ at
In brief: The simplest way to code an image is by using sample values that are directly proportional to the intensity of the color components. But that wastes the sample space because the human eye can't discern differences between low-intensity colors as well as it can between high-intensity colors. So instead, we pass the light intensity values through a transfer function that makes it so that changing a sample value by 1 causes the same level of perceived color change anywhere in the sample range. We store those resulting values in the image file. That transfer function is called the gamma transfer function and the transformation is called gamma correcting.
Virtually all image formats, either specified or de facto, use gamma-corrected values for their sample values.
What's really nice about gamma is that by coincidence, the inverse function that you have to do to convert the gamma-corrected values back to real light intensities is done automatically by CRTs. You just apply a voltage to the CRT's electron gun that is proportional to the gamma-corrected sample value, and the intensity of light that comes of the screen is close to the intensity value you had before you applied the gamma transfer function!