TYPES AND CONSTANTS
Each
R pixel
contains three
R pixval s,
each of which should contain only the values between
R 0
and
R PPM_MAXMAXVAL .
R ppm_pbmmaxval
is the maxval used when a PPM program reads a PBM file.
Normally it is 1; however, for some programs, a larger value gives better
results.
MANIPULATING PIXELS
The macros
R PPM_GETR ,
R PPM_GETG ,
and
PPM_GETB
retrieve the red, green, or blue sample, respectively, from the given pixel.
The
PPM_ASSIGN
macro assigns the given values to the red, green, and blue samples of
the given pixel.
The
PPM_EQUAL
macro tests two pixels for equality.
The
PPM_DEPTH
macro
scales the colors of pixel
p
according the old and new maxvals and assigns the new values to
R newp .
It is intended to make writing ppmtowhatever easier.
The
R PPM_LUMIN ,
R PPM_CHROM_R ,
and
R PPM_CHROM_B ,
macros determine the luminance, red chrominance, and blue chrominance,
respectively, of the pixel
R p .
The scale of all these values is the same as the scale of the input samples
(i.e. 0 to maxval for luminance, -maxval/2 to maxval/2 for chrominance).
Note that the macros do it by floating point multiplication. If you are
computing these values over an entire image, it may be significantly faster
to do it with multiplication tables instead. Compute all the possible
products once up front, then for each pixel, just look up the products in
the tables.
INITIALIZATION
All PPM programs must call
ppm_init()
just after invocation, before they process their arguments.
MEMORY MANAGEMENT
ppm_allocarray()
allocates an array of pixels.
ppm_allocrow()
allocates a row of the given number of pixels.
ppm_freearray()
frees the array allocated with
ppm_allocarray()
containing the given number of rows.
ppm_freerow()
frees a row of pixelss allocated with
R ppm_allocrow() .
READING FILES
If a function in this section is called on a PBM or PGM format file,
it translates the PBM or PGM file into a PPM file on the fly and
functions as if it were called on the equivalent PPM file. The
format
value returned by
ppm_readppminit()
is, however, not translated. It represents the actual format of the
PBM or PGM file.
ppm_readppminit()
reads the header of a PPM file, returning all the information from the header
and leaving the file positioned just after the header.
ppm_readppmrow()
reads a row of pixels into the
pixelrow
array.
R format ,
R cols ,
and
maxval
are the values returned by
R ppm_readppminit() .
ppm_readppm()
reads an entire PPM image into memory, returning the allocated array as
its return value and returning the information from the header as
R rows ,
R cols ,
and
R maxval .
This function combines
R ppm_readppminit() ,
R ppm_allocarray() ,
and
R ppm_readppmrow() .
WRITING FILES
ppm_writeppminit()
writes the header for a PPM file and leaves it positioned just after
the header.
forceplain
is a logical value that tells
ppm_writeppminit()
to write a header for a plain PPM format file, as opposed to a raw PPM
format file.
ppm_writeppmrow()
writes the row
pixelrow
to a PPM file. For meaningful results,
R cols ,
R maxval ,
and
forceplain
must be the same as was used with
R ppm_writeppminit() .
ppm_writeppm()
write the header and all data for a PPM image. This function
combines
ppm_writeppminit()
and
R ppm_writeppmrow() .
MISCELLANEOUS
ppm_nextimage()
positions a PPM input file to the next image in it (so that a subsequent
ppm_readppminit()
reads its header).
ppm_nextimage()
is analogous to
R pbm_nextimage() ,
but works on PPM, PGM, and PBM files.
ppm_check()
checks for the common file integrity error where the file is the wrong
size to contain all the image data.
ppm_check()
is analogous to
R pbm_check() ,
but works on PPM, PGM, and PBM files.
COLOR NAMES
ppm_parsecolor()
Interprets a color specification and returns a pixel of the color that
it indicates. The color specification is ASCII text, in one of
three formats: 1) a name, as defined in the system's
X11-style color names file (e.g.
R rgb.txt ).
2) an X11-style
hexadecimal triple: #rgb, #rrggbb, #rrrgggbbb, or #rrrrggggbbbb.
3) A triplet of decimal floating point numbers from 0.0 to 1.0,
representing red, green, and blue intensities respectively, separated by
commas. E.g. "1.0, 0.5, .25".
If the color specification does not conform to any of these formats,
including the case that it is a name, but is not in the rgb.txt database,
ppm_parsecolor()
exits the program via
R pm_error() .
ppm_colorname()
Returns a string that describes the color of the given pixel.
If an X11-style color names file (e.g.
R rgb.txt )
is available and the color appears in
it,
ppm_colorname()
returns the name of the color from the file.
If the color does not appear in a X11-style color file and
hexok
is true,
ppm_colorname()
returns a
hexadecimal color specification triple (#rrggbb).
If a X11-style color file is available but the color does not appear in
it and
hexok
is false,
ppm_colorname()
returns the name of the closest matching color in the color file.
Finally, if their is no X11-style color file available and
hexok
is false,
ppm_colorname()
fails and exits the program with an error message.
The string returned is in static libppm library storage which is overwritten
by every call to
R ppm_colorname() .
COLOR INDEXING
Sometimes in processing images, you want to associate a value with a
particular color. Most often, that's because you're generating a
color mapped graphics format. In a color mapped graphics format, the
raster contains small numbers, and the file contains a color map that
tells what color each of those small numbers refers to. If your image
has only 256 colors, but each color takes 24 bits to describe, this
can make your output file much smaller than a straightforward RGB
raster would.
So, continuing the above example, say you have a
pixel
value for chartreuse and in your output file and you are going to
represent chartreuse by the number 12. You need a data structure that
allows your program quickly to find out that the number for a
chartreuse
R pixel
is 12.
Netpbm's color indexing data types and functions give you that.
colorhash_table
is a C data type that associates an integer with each of an arbitrary
number of colors. It is a hash table, so it uses far less space than
an array indexed by the color's RGB values would.
The problem with a
colorhash_table
is that you can only look things up in it. You can't find out what colors
are in it. So Netpbm has another data type for representing the same
information, the poorly but historically named
R colorhist_vector .
A
colorhist_vector
is just an array. Each entry represents a color and contains the color's
value (as a
R pixel )
and the integer value associated with it. The entries are filled in
starting with subscript 0 and going consecutively up for the number of colors
in the histogram.
(The reason the name is poor is because a color histogram is only one of
many things that could be represented by it).
colorhash_table ppm_alloccolorhash()
This creates a
colorhash_table
using dynamically allocated storage. There are no colors in it. If
there is not enough storage, it exits the program with an error
message.
void ppm_freecolorhash()
This destroys a
ppm_freecolorhash
and frees all the storage associated with it.
int ppm_addtocolorhash( colorhash_table cht, const pixel * const colorP,
const int value)
This adds the specified color to the specified
colorhash_table
and associates the specified value with it.
You must ensure that the color you are adding isn't already present in
the
R colorhash_table .
There is no way to update an entry or delete an entry from a
R colorhash_table .
int ppm_lookupcolor( const colorhash_table cht, const pixel * const colorP )
This looks up the specified color in the specified
R colorhash_table .
It returns the integer value associated with that color.
If the specified color is not in the hash table, the function returns
-1. (So if you assign the value -1 to a color, the return value is
ambiguous).
colorhist_vector ppm_colorhashtocolorhist( const colorhash_table cht,
const int ncolors )
This converts a
colorhash_table
to a
R colorhist_vector .
The return value is a new
colorhist_vector
which you must eventually free with
R ppm_freecolorhist() .
ncolors
is the number of colors in
R cht .
If it has more colors than that,
ppm_colorhashtocolorhist
does not create a
colorhist_vector
and returns NULL.
colorhash_table ppm_colorhisttocolorhash( const colorhist_vector chv,
const int ncolors )
This poorly named function does
not
convert from a
colorhist_vector
to a
R colorhash_table .
It does create a
colorhash_table
based on a
colorhist_vector
input, but the integer value for a given color in the output is not the same
as the integer value for that same color in the input.
ppm_colorhisttocolorhash()
ignores the integer values in the input. In the output, the integer value
for a color is the index in the input
colorhist_vector
for that color.
You can easily create a color map for an image by running
ppm_computecolorhist()
over the image, then
ppm_colorhisttocolorhash()
over the result. Now you can use
ppm_lookupcolor()
to find a unique color index for any pixel in the input.
If the same color appears twice in the input,
ppm_colorhisttocolorhash()
exit the program with an error message.
ncolors
is the number of colors in
R chv .
The return value is a new
colorhash_table
which you must eventually free with
R ppm_freecolorhash() .
COLOR HISTOGRAMS
The Netpbm libraries give you functions to examine a Netpbm image and
determine what colors are in it and how many pixels of each color are in
it. This information is known as a color histogram. Netpbm uses its
colorhash_table
data type to represent a color histogram.
colorhash_table ppm_computecolorhash( pixel ** const pixels,
const int cols, const int rows, const int maxcolors, int* const colorsP )
This poorly but historically named function
generates a
colorhash_table
whose value for each color is the number of pixels in a specified
image that have that color. (I.e. a color histogram). As a bonus, it
returns the number of colors in the image.
(It's poorly named because not all
R colorhash_table s
are color histograms, but that's all it generates).
R pixels , cols , and rows
describe the input image.
maxcolors
is the maximum number of colors you want processed. If there are more colors
that that in the input image,
ppm_computecolorhash()
returns NULL as its return value and stops processing as soon as it
discovers this. This makes it run faster and use less memory. One use
for
maxcolors
is when you just want to find out whether or not the image has more than
N colors and don't want to wait to generate a huge color table if so.
If you don't want any limit on the number of colors, specify
R maxcolors = 0 .
ppm_computecolorhash()
returns the actual number of colors in the image as
R *colorsP ,
but only if it is less than or equal to
R maxcolors .
colorhash_table ppm_computecolorhash2( FILE * const ifp,
const int cols, const int rows, const pixval maxval, const int format,
const int maxcolors, int* const colorsP )
This is the same as
ppm_computecolorhash()
except that instead of feeding it an array of pixels in storage, you give
it an open file stream and it reads the image from the file. The file must
be positioned after the header, at the raster. Upon return, the file is
still open, but its position is undefined.
maxval
and
format
are the values for the image (i.e. information from the file's header).
colorhist_vector ppm_computecolorhist( pixel ** pixels,
int cols, int rows, int maxcolors, int * colorsP )
This is like
ppm_computecolorhash()
except that it creates a
colorhist_vector
instead of a
R colorhash_table .
If you supply a nonzero
maxcolors
argument, that is the maximum number of colors you expect to find in
the input image. If there are more colors than you say in the image,
R ppm_computecolorhist()
returns a null pointer as its return value and nothing meaningful as
R *colorsP .
If not, the function returns the
new
colorhist_vector
as its return value and the actual number of colors in the image as
R *colorsP .
The returned array has space allocated for the specified number of
colors regardless of how many actually exist. The extra space is at
the high end of the array and is available for your use in expanding
the
R colorhist_vector .
If you specify
R maxcolors = 0 ,
there is no limit on the number of colors returned and the return array has
space for 5 extra colors at the high end for your use in expanding the
R colorhist_vector .
colorhist_vector ppm_computecolorhist2( FILE * ifp,
int cols, int rows, int maxcolors, pixval maxval, int format,
int * colorsP )
This is the same as
ppm_computecolorhist()
except that instead of feeding it an array of pixels in storage, you give
it an open file stream and it reads the image from the file. The file must
be positioned after the header, at the raster. Upon return, the file is
still open, but its position is undefined.
Copyright (C) 1989, 1991 by Tony Hansen and Jef Poskanzer.