NAME¶
libpnm - functions to support pnm and pam programs
EXAMPLE¶
/* Example program fragment to read a PAM or PNM image
from stdin, add up the values of every sample in it
(I don't know why), and write the image unchanged to
stdout. */
#include <pam.h>
struct pam inpam, outpam; unsigned int row;
pnm_init(&argc, argv);
pnm_readpaminit(stdin, &inpam, sizeof(inpam));
outpam = inpam; outpam.file = stdout;
pnm_writepaminit(&outpam);
tuplerow = pnm_allocpamrow(&inpam);
for (row = 0; row < inpam.height; row++) {
unsigned int col;
pnm_readpamrow(&inpam, tuplerow);
for (column = 0; column < inpam.width; column++) {
unsigned int plane;
for (plane = 0; plane < inpam.depth; column++) {
grand_total += tuplerow[row][column][plane];
}
}
pnm_writepamrow(&outpam, tuplerow); }
pnm_freepamrow(tuplerow);
SYNOPSIS¶
#include <pnm.h>
void pnm_init( int *argcP, char
*argv[] );
tuple ** pnm_allocpamarray( struct pam *pamP);
xel ** pnm_allocarray( int cols, int
rows);
tuple * pnm_allocpamrow( struct pam *pamP);
xel * pnm_allocrow( int cols);
void pnm_freepamarray( tuple **tuplearray, struct
pam *pamP);
void pnm_freearray( xel **xels, int
rows);
void pnm_freepamrow( tuple *tuplerow);
void pnm_freerow( xel *xelrow);
tuple * allocpamtuple( struct pam *pamP);
void pnm_freepamtuple( tuple tuple );
void pnm_readpaminit( FILE *file, struct pam
*pamP, int size);
void pnm_readpnminit( FILE *fp, int
*colsP, int *rowsP, xelval
*maxvalP, int *formatP );
void pnm_readpamrow( struct pam *pamP, tuple
*tuplerow);
void pnm_readpnmrow( FILE *fp, xel
*xelrow, int cols,
xelval maxval, int format );
tuple ** pnm_readpam( FILE *file, struct pam
*pamP,
int size);
xel ** pnm_readpnm( FILE *fp, int
*colsP, int *rowsP,
xelval *maxvalP, int* formatP
);"
void pnm_writepaminit( struct pam *pamP);
void pnm_writepnminit( FILE * fp , int cols,
int rows, xelval maxval, int
format, int forceplain);
void pnm_writepamrow( struct pam *pamP, const
tuple *tuplerow);
void pnm_writepnmrow( FILE *fp, xel
*xelrow, int cols, xelval
maxval, int format, int
forceplain );
void pnm_writepam( struct pam *pamP, const tuple
* const *tuplearray);
void pnm_writepnm( FILE *fp, xel **
xels, int cols, int
rows, xelval maxval, int
format, int forceplain );
void pnm_checkpam( struct pam *pamP, const enum
pm_check_type check_type, enum pm_check_code
*retvalP);
void pnm_nextimage( FILE *file, int * const
eofP);
void pnm_check( FILE * file, const enum
pm_check_type check_type, const int
format, const int cols, const int
rows, const xelval maxval, enum
pm_check_code *retvalP);
void pnm_promoteformatrow( xel *xelrow, int
cols, xelval maxval, int
format, xelval newmaxval, int
newformat);
void pnm_promoteformatrow( xel **xels, int
cols, xelval maxval, int
format, xelval newmaxval, int
newformat);
xel pnm_whitexel( xelval maxval, int
format);
xel pnm_blackxel( xelval maxval, int
format);
void pnm_invertxel( xel *x, xelval
maxval, int format);
xel pnm_backgroundxelrow( xel *xelrow, int
cols, xelval maxval, int
format);
xel pnm_backgroundxel( xel **xels, int
cols, int rows, xelval
maxval, int format);
void pnm_YCbCrtuple( tupletuple, double
*YP, double *CrP, double
*CbP);
struct pam {
int size
int len
FILE * file
int format
int plainformat
int height
int width
int depth
sample maxval
int bytes_per_sample
char tuple_type[256]; }
typedef ... sample;
typedef ... tuple;
typedef ... xelval;
typedef ... xel;
extern xelval pnm_pbmmaxval;
#define PNM_MAXMAXVAL ...
#define PNM_OVERALLMAXVAL ...
#define PNM_FORMAT ...
#define PNM_ASSIGN1(x,v) ...
#define PNM_GET1(x) ...
#define PNM_EQUAL(x,y) ...
#define PAM_FORMAT_TYPE(format) ...
#define PNM_FORMAT_TYPE(format) ...
DESCRIPTION¶
PAM VERSUS PNM FUNCTIONS¶
The PNM library contains two classes of functions: The pam functions and the pnm
functions. The pam functions are enhancements of the pnm functions and you
should use them unless you need to be compatible with older PNM libraries that
don't have them (those released before August 2000).
The pnm functions operate on PBM, PGM, and PPM images and files. They are
similar to the functions in the PBM, PGM, and PPM libraries, except the pnm
functions let you operate on all three, both reading and writing, without a
lot of concern for which of the three formats you are processing.
The pam functions provide all the same functions for operating on PBM, PGM, and
PPM libraries, but also operate on the newer PAM images and files. The pam
functions are easier to use than the pnm functions due to improved parameter
lists.
There is no separate PAM library specific to the PAM format, as there is for
PBM, PGM, and PPM.
THE pam STRUCTURE¶
The pam functions take most of their arguments in the form of a single
pam structure. This is not an opaque object, but just a convenient way
to organize the information upon which most the functions depend. So you are
free to access or set the elements of the structure however you want. But you
will find in most cases it is most convenient to call
pnm_readpaminit()
or
pnm_writepaminit() to set the fields in the
pam structure
before calling any other pam functions, and then just to pass the structure
unchanged in all future calls to pam functions.
The fields are:
- size
- The storage size in bytes of this entire structure.
- len
- The length, in bytes, of the information in this structure. The
information starts in the first byte and is contiguous. This cannot be
greater than size. size and len can be used to make
programs compatible with newer and older versions of the Netpbm
libraries.
- file
- The file.
- format
- The format code of the raw image. This is PAM_FORMAT unless the PAM
image is really a view of a PBM, PGM, or PPM image. Then it's
PBM_FORMAT, RPBM_FORMAT, etc.
- plainformat
- This is a boolean value and means: The format above is a plain (text)
format as opposed to a raw (binary) format. This is entirely redundant
with the format member and exists as a separate member only for
computational speed.
- height
- The height of the image in rows.
- width
- The width of the image in number of columns (tuples per row).
- depth
- The depth of the image (degree of or number of samples in each
tuple).
- maxval
- The maxval of the image. See definitions in pam(5).
- bytes_per_sample
- The number of bytes used to represent each sample in the image file. See
the format definition in pam(5). This is entirely redundant with
maxval. It exists as a separate member for computational
speed.
- tuple_type
- The tuple type of the image. See definitions in pam(5). Netpbm does not
define any values for this except the following, which are used for a PAM
image which is really a view of a PBM, PGM, or PPM image:
PAM_PBM_TUPLETYPE, PAM_PGM_TUPLETYPE,
PAM_PPM_TUPLETYPE.
The PNM formats each come in two varieties: the older plain (text) format and
the newer raw (binary) format. There are different format codes for the plain
and raw formats, but which of the two formats the pnm and pam functions write
is independent of the format code you pass to them.
The pam functions always write raw formats. If you specify the format code for a
plain format, a pam function assumes instead the raw version of that format.
The pnm functions choose between plain and raw based on the
forceplain
parameter that every write-type pnm function has. If this boolean value is
true, the function writes the plain version of the format specified by the
format code. If it is false, the function writes the raw version of the format
specified by the format code.
We are trying to stamp out the older plain formats, so it would be a wise choice
not to write a program that sets
forceplain true under any
circumstance. A user who needs a plain format can use the
pnmtoplainpnm
program to convert the output of your program to plain format.
PNM TYPES AND CONSTANTS¶
Each
xel contains three
xelvals, each of which should contain only
the values between
0 and
PNM_MAXMAXVAL, inclusive.
pnm_pbmmaxval is the maxval used when a PNM program reads a PBM file.
Normally it is 1; however, for some programs, a larger value gives better
results.
PNM XEL MANIPULATIONS¶
The
PNM_GET1 macro extracts a single value from an xel, when you know
it's from a PBM or PGM file. When it's from a PPM file, use
PPM_GETR(),
PPM_GETG(), and
PPM_GETB().
The
PNM_ASSIGN1 macro assigns a single value to an xel, when you know
it's from a PBM or PGM file. When it's from a PPM file, use
PPM_ASSIGN.
The
PNM_EQUAL macro checks two xels for equality. The
PNM_FORMAT_TYPE and
PAM_FORMAT_TYPE macros compute a format type
code from a format code. The format types are PBM, PGM, PPM, and PAM. But note
that PBM, PGM, and PPM each are two different formats: a plain one and a raw
one. So there are four format types, but seven formats.
PNM_FORMAT_TYPE
does not work on the PAM format code.
INITIALIZATION¶
All PNM and PAM programs must call
pnm_init() just after startup, before
they process their arguments.
pnm_init(), among other things, processes Netpbm universal parameters and
removes them from the parameter list.
MEMORY MANAGEMENT¶
pnm_allocpamarray() allocates space for an array of tuples.
pnm_freepamarray() frees an array space allocated by
pnm_allocpamarray() or
pnm_readpam().
pnm_allocarray() allocates space for an array of xels.
pnm_freearray() frees an array space allocated by
pnm_allocarray() or
pnm_readpnm().
pnm_allocpamrow() allocates space for a row of a PAM image.
pnm_freepamrow() frees it.
pnm_allocrow() allocates space for a row of a PNM image.
pnm_freerow() frees it.
READING PNM FILES¶
pnm_readpaminit() reads the header of a PAM or PNM image. It returns the
information from the header in the
*pamP structure. It does not
require any members of
*pamP to be set at invocation, and sets
every member.
size is the storage size of the
*pamP
structure, normally
sizeof(struct pam).
The function expects to find the image file positioned to the start of the
header and leaves it positioned to the start of the raster.
pnm_readpnminit() is similar to
pnm_readpaminit(), but reads only
PNM images and has a different parameter list.
pnm_readpamrow() reads a row of the raster from a PAM or PNM image file.
It expects all of the members of the
*pamP structure to be set upon
invocation and does not modify any of them. It expects to find the file
positioned to the start of the row in question in the raster and leaves it
positioned just after it. It returns the row as the array of tuples
tuplerow, which must already have its column pointers set up so that it
forms a C 2-dimensional array. The leftmost tuple is Element 0 of this array.
pnm_readpnmrow() is similar to
pnm_readpamrow() but only works on
PNM images and has a different parameter list and returns the row as an array
of xels instead of tuples.
pnm_readpam() reads an entire image from a PAM or PNM image file and
allocates the space in which to return the raster. It expects to find the file
positioned to the first byte of the image and leaves it positioned just after
the image.
The function does not require
*pamP to have any of its members set
and sets them all.
size is the storage size in bytes of the
*pamP structure, normally
sizeof(struct pam).
The return value is a newly allocated array of the rows of the image, with the
top row being Element 0 of the array. Each row is represented as
pnm_readpamrow() would return.
The return value is also effectively a 3-dimensional C array of samples, with
the dimensions corresponding to the height, width, and depth of the image, in
that order.
pnm_readpam() combines the functions of
pnm_allocpamarray(),
pnm_readpaminit(), and iterations of
pnm_readpamrow(). It may
require more dynamic storage than you can afford.
pnm_readpnm() is similar to
pnm_readpam() except that it reads
only PNM images and uses a different parameter list and returns an array of
rows such that
pnm_readpnmrow() would return rather than such that
pnm_readpamrow() would return.
WRITING FILES¶
pnm_writepnminit() writes the header of a PAM or PNM image and computes
some of the fields of the pam structure.
The following members of the
*pamP structure must be set upon
invocation to tell the function how and what to write.
size,
len,
file,
format,
height,
width,
depth,
maxval,
tuple_type.
pnm_writepaminit() sets the
plainformat and
bytes_per_sample members based on the information supplied.
pnm_writepnminit() is similar to
pnm_writepaminit() except that it
can write only a PNM header and has a different parameter list.
See the description of
forceplain above.
pnm_writepamrow() writes a row of the raster into a PAM or PNM image
file. It expects to find the file positioned where the row should start and
leaves it positioned just after the row. The function requires all the
elements of
*pamP to be set upon invocation and doesn't modify
them.
tuplerow is an array of tuples representing the row. The leftmost tuple
is Element 0 of this array.
pnm_writepnmrow() is similar to
pnm_writepamrow() except that it
works only on PNM images and has a different parameter list and takes an array
of xels instead of an array of tuples. See the description of
forceplain above.
pnm_writepam() writes an entire PAM or PNM image to a PAM or PNM image
file. It expects to find the file positioned to where the image should start
and leaves it positioned just after the image.
The following members of the
*pamP structure must be set upon
invocation to tell the function how and what to write:
size,
len,
file,
format,
height,
width,
depth,
maxval,
tuple_type.
pnm_writepam() sets the
plainformat and
bytes_per_sample
members based on the information supplied.
tuplearray is an array of rows such that you would pass to
pnm_writepamrow(), with the top row being Element 0 of the array.
pnm_writepam() combines the functions of
pnm_writepaminit(), and
iterations of
pnm_writepamrow(). It's raster input may be more storage
than you can afford.
pnm_writepnm() is similar to
pnm_writepam() except that it works
only on PNM image, has a different parameter list, and takes an array of rows
of xels instead of an array of rows of tuples. See the description of
forceplain above.
MISCELLANEOUS¶
pnm_nextimage() positions a PNM input file to the next image in it (so
that a subsequent
pnm_readpnminit() reads its header).
pnm_nextimage() is identical to
pbm_nextimage().
pam_check() checks for the common file integrity error where the file is
the wrong size to contain the raster, according to the information in the
header. This works on PAM and PNM images.
pnm_check() is similar to
pam_check() except it works only on PNM
images.
pnm_check() is identical to
ppm_check().
pnm_promoteformatrow() promotes a row of xels from one maxval and format
to a new set. Use this when you are combining multiple anymaps of different
types - just take the maximum of the maxvals and the maximum of the formats,
and promote them all to that.
pnm_promoteformat() promotes an entire anymap.
PNM XEL MANIPULATION¶
pnm_whitexel() and
pnm_blackxel() return a white or black xel,
respectively, for the given
maxval and
format.
pnm_invertxel() inverts an xel.
pnm_backgroundxelrow() figures out an appropriate background xel based on
the row of xels
xelrow, which is
cols xels wide, has maxval
maxval, and represents an image with format
format.
This estimate works best when the row is the top or bottom row of the image.
pnm_backgroundxel() does the same thing as
pnm_backgroundxelrow(),
except based on an entire image instead of just one row. This tends to do a
slightly better job than
pnmbackgroundxelrow().
pnm_YCbCrtuple() Returns the Y/Cb/Cr luminance/chrominance representation
of the color represented by the input tuple, assuming that the tuple is an RGB
color representation (which is the case if it was read from a PPM image). The
output components are based on the same scale (maxval) as the input tuple, but
are floating point nonetheless to avoid losing information due to rounding.
Divide them by the maxval to get normalized [0..1] values.
SEE ALSO¶
pbm(5),
pgm(5),
ppm(5),
pam(5),
libpbm(3),
libpgm(3),
libppm(3)
AUTHOR¶
Copyright (C) 1989, 1991 by Tony Hansen and Jef Poskanzer.