Make a Negative of a Greyscale Image

Your task is to convert this:

Moon Phases

into this:

Moon Phases

Images

An image is represented as a 2-dimensional array, just like the game of life simulation grid. As with ncurses, libnetpbm uses the y,x convention with the origin in the upper left corner.

For greyscale images, each element (pixel) of the grid is an intensity value, which is an integer usually between 0 and 255. The lower the intensity, the darker the pixel.

netpbm

netpbm is a set of tools and a library for simple image processing. libnetpbm is the C library for reading, writing, and manipulating netpbm images.

netpbm images are one of three types: PBM (each pixel is either black or white), PGM (greyscale), and PPM (color). Other types of images with which you might be familiar include JPEG, PNG, or GIF; for libnetpbm to work with these non-netpbm images you must convert them to the appropriate type. You can use the convert program which is a part of the ImageMagick toolkit, or you can use the netpbm tools. I recommend using convert, like this:

convert foo.jpg foo.pgm

Because color images involve three values per pixel (red, green, and blue), it is simpler to work with greyscale images (PGM). For your convenience you can download this PGM image of the moon to work with.

To display PGM images, use the program display which is also part of ImageMagick, like so:

display foo.pgm

This will only work in the graphical environment in the lab. If you have trouble with that, try converting to a JPEG with convert and looking at it with your web browser or favorite image-viewing program.

Unfortunately, the libnetpbm documentation is somewhat difficult to read and has a downright incorrect example, so I have written a PGM reference that you can refer to.

Negative

Making a negative of a greyscale image is simple enough. Intensity 0 becomes intensity 255 (black becomes white), and vice versa. Intensity 1 becomes intensity 254, and vice versa. Etc. The mathematical equation is new_intensity = max_intensity - old_intensity.

Assignment

Write a program that takes a PGM file on stdin and writes a PGM file which is the negative of that image on stdout. Your program should run like this:

./negative < moon.pgm > moon-negative.pgm

CS 467

Graduate students should work with color images (PPM) instead of grayscale. You will use the corresponding ppm functions, e.g. ppm_init, ppm_readppm, etc. as documented in the libppm manual. Taking a negative of a color image means inverting the intensity of red, green, and blue in each pixel. In actuality can can get more complicated than that, but that will be good enough.

To get and set the red, green, and blue values you will use the macros PPM_GETR, PPM_GETG, PPM_GETB, and PPM_ASSIGN, which are documented in the libppm manual.

Your program will run like this:

./negative < lena.ppm > lena-negative.ppm

I have converted two standard images to ppm format for you: Lena and Mandrill.

The end result should look something like this:

Lena Negative