The libnetpbm documentation is a little bit hard to read, and we will only need to use a small subset which is documented on this page.
The example C program given in the libnetpbm documentation is not even close to a valid program, and uses many features which we do not need. Here is a more relevant example:
#include <pgm.h>
/* reduce the image intensity by 1/2 */
int main(int argc, char *argv[])
{
/* image is a pointer to a 2d array that we will point at an array that
* pgm_readpgm will allocate */
gray **image;
/* This will be set to the maximum value of our input image, probably
* 255 */
gray max;
/* These will be set to the number of rows and columns in the input
* (and output) image. */
int cols, rows;
/* Indexes that we will use to access pixels at y,x */
int y, x;
/* initialize libpgm. pgm_init wants argv and a pointer to argc, which
* is why we don't just do int main(void) above. */
pgm_init(&argc, argv);
/* read the image from stdin. the data is in image, and the number of
* cols and rows, and the maximum intensity value are saved in the
* respective variables. */
image = pgm_readpgm(stdin, &cols, &rows, &max);
/* make image half as intense (darker) */
for (y=0; y<rows; y++)
for (x=0; x<cols; x++)
image[y][x] = image[y][x]/2;
/* write the modified image to stdout */
pgm_writepgm(stdout, image, cols, rows, max, 1);
/* cleanup */
pgm_freearray(image, rows);
/* Success */
return 0;
}
The libnetpbm functions relevant for this program are the following:
void pgm_init( int *argcP, char *argv[] );
Every PGM program must call this
function at the beginning of the program. It takes a pointer to argc
(the
number of command-line arguments) and argv
(the array of command-line
arguments), therefore you have to use the int main(int argc, char *argv[])
prototype for your main function.
gray ** pgm_readpgm( FILE *fp, int *colsP, int *rowsP, gray *maxvalP );
This function reads a PGM file from fp
(you can use stdin
), and stores the
number of columns in *colsP
, the number of rows in *rowsP
, and the
maximum intensity value in *maxvalP
. A pointer to a 2d array containing the
image data (y,x starting in the upper-left corner) is returned.
void pgm_writepgm( FILE *fp, gray ** grays, int cols, int rows, gray maxval, int forceplain );
This function writes the PGM image stored in
grays
to fp
(you can use stdout
). The image is cols
x rows
in size
and has a maximum intensity value of maxval
. Set forceplain
to either 0
or 1; it doesn't matter which for this lab, but you can more read about it in
the documentation if you're curious.
void pgm_freearray( gray **grays, int rows );
This function will free a
dynamically-allocated array pointed at by grays
with rows
rows.