1Libnetpbm Image Processing MLainburaalr(y3)FunctionLsibMnaentupablm Image Processing Manual(3)
2
3
4
5       Table Of Contents ⟨#toc⟩
6

NAME

8       libnetpbm_image - overview of netpbm image-processing functions
9

DESCRIPTION

11       This  reference  manual  covers  functions in the libnetpbm library for
12       processing images, using the Netpbm image formats and the libnetpbm in-
13       memory image formats.
14
15       For  historical  reasons as well as to avoid clutter, it does not cover
16       the largely obsolete PBM, PGM, PPM, and PNM classes of libnetpbm  func‐
17       tions.   For  those,  see  PBM  Function Manual" (1), PGM Function Man‐
18       ual(1), PPM Function Manual(1), and PNM Function Manual(1).  Note  that
19       you  do  not  need  those  functions  to process PBM, PGM, PPM, and PNM
20       images.  The functions in this manual are sufficient for that.
21
22       The PPM drawing functions are covered separately in PPM  Drawing  Func‐
23       tion Manual(1).
24
25       For introductory and general information using libnetpbm, see Libnetpbm
26       User's Guide(1).
27
28       libnetpbm also contains functions that are  not  specifically  oriented
29       toward  processing image data.  Read about those in the Libnetpbm Util‐
30       ity Manual(1).
31
32       To use these services, #include pam.h.
33
34
35

Types

37       Here are some important types that you use with libnetpbm:
38
39
40
41
42       sample A sample of a Netpbm image.  See the format specifications -- as
43              an  example,  the  red  intensity of a particular pixel of a PPM
44              image is a sample.  This is an integer type.
45
46
47       tuple  A tuple from a PAM image or the PAM equivalent of a  PNM  image.
48              See  the PAM format specification -- as an example, a pixel of a
49              PPM image would be a tuple.  A tuple is an array of samples.
50
51
52       samplen
53              Same as sample, except in normalized form.  This is  a  floating
54              point  type  with a value in the range 0..1.  0 corresponds to a
55              PAM/PNM sample value of 0.  1 corresponds to  a  PAM/PNM  sample
56              value equal to the image's maxval.
57
58
59       tuplen The  same  as tuple, except composed of normalized samples (sam‐
60              plen) instead of regular samples (sample).
61
62
63
64
65
66   struct pam
67       The main argument to most of the PAM functions is the address of a  pam
68       structure, which is defined as follows:
69
70
71           struct pam {
72               int size
73               int len
74               FILE *file
75               int format
76               int plainformat
77               int height
78               int width
79               int depth
80               sample maxval
81               int bytes_per_sample
82               char tuple_type[256]
83               int allocation_depth
84               char **comment_p;
85           }
86
87
88       See The Libnetbm User's Guide ⟨libnetpbm_ug.html#pamstruct⟩  for infor‐
89       mation on the pam structure.
90
91
92

Macros

94       PNM_MAXMAXVAL is the maximum maxval that Netpbm images  could  histori‐
95       cally  have:  255.   Many  programs  aren't  capable of handling Netpbm
96       images with a maxval larger than this.  It's named this way  for  back‐
97       ward  compatibility  --  it  had this name back when it was the maximum
98       maxval.
99
100       PNM_OVERALLMAXVAL is the maximum maxval that  Netpbm  images  can  have
101       today (65535).
102
103       PBM_FORMAT, RPBM_FORMAT, PGM_FORMAT, RPGM_FORMAT, PPM_FORMAT, RPPM_FOR‐
104       MAT, and PAM_FORMAT are the format codes of the various Netpbm formats.
105       RPBM_FORMAT  is the raw PBM format and PBM_FORMAT is the plain PBM for‐
106       mat,  and  so  on.   See  the  format  member  of  the  pam   structure
107       ⟨libnetpbm_ug.html#pamstruct⟩ .
108
109       PAM_FORMAT_TYPE(format)  gives  the  type of a format, given the format
110       code.  The types of formats are PBM, PGM, PPM, and PAM and  macros  for
111       the  type  codes  are,  respectively, PBM_TYPE, PGM_TYPE, PPM_TYPE, and
112       PAM_TYPE.  Note that there are more format codes then there are  format
113       types  because  there  are different format codes for the plain and raw
114       subformats of each format.
115
116       Macros for the tuple types that are defined by Netpbm are  as  follows.
117       See     the     tuple_type     member     of    the    pam    structure
118       ⟨libnetpbm_ug.html#pamstruct⟩ .
119
120
121       ·      PAM_PBM_TUPLETYPE
122
123       ·      PAM_PGM_TUPLETYPE
124
125       ·      PAM_PPM_TUPLETYPE
126
127       ·      PAM_PBM_ALPHA_TUPLETYPE
128
129       ·      PAM_PGM_ALPHA_TUPLETYPE
130
131       ·      PAM_PPM_ALPHA_TUPLETYPE
132
133
134
135

Functions

137       These interfaces are declared in pam.h.
138
139
140   Memory Management
141       Synopsis
142
143       tuple ** pnm_allocpamarray( struct pam *pamP);
144
145       tuple * pnm_allocpamrow( struct pam *pamP);
146
147       void pnm_freepamarray( tuple **tuplearray, struct pam *pamP);
148
149       void pnm_freepamrow( tuple *tuplerow);
150
151       tuple * allocpamtuple( struct pam *pamP);
152
153       void pnm_freepamtuple( tuple tuple );
154
155       tuplen * pnm_allocpamrown( struct pam *pamP);
156
157       void pnm_freepamrown( tuplen *tuplenrow);
158
159
160
161       Description
162
163       pnm_allocpamarray()  allocates  space   for   an   array   of   tuples.
164       pnm_freepamarray()  frees  an  array space allocated by pnm_allocpamar‐
165       ray() or pnm_readpam().
166
167       pnm_allocpamrow()  allocates space for a row of a PAM image,  in  basic
168       form.  pnm_freepamrow() frees it.
169
170       pnm_allocpamrown()  is  the  same  as  pnm_allocpamrow() except that it
171       allocates space for a PAM row in  the  normalized  form.   pnm_freepam‐
172       rown() is similarly like pnm_freepamrow.
173
174
175
176   Reading Netpbm Files
177       Synopsis
178
179       void pnm_readpaminit( FILE *file, struct pam *pamP, int size);
180
181       void pnm_readpamrow( struct pam *pamP, tuple *tuplerow);
182
183       tuple ** pnm_readpam( FILE *file, struct pam *pamP, int size);
184
185       void pnm_readpamrown( struct pam *pamP, tuplen *tuplenrow);
186
187
188       Description
189
190       pnm_readpaminit() reads the header of a Netpbm image.
191
192       See above for a general description of the pamP argument.
193
194       pnm_readpaminit()  returns the information from the header in the *pamP
195       structure.  It does not require any members of *pamP through tuple_type
196       to be set at invocation, and sets all of those members.  It expects all
197       members after tuple_type to be meaningful.
198
199       size is the size of the *pamP structure as understood  by  the  program
200       processing the image.  pnm_readpaminit() does not attempt to use or set
201       any members of the structure beyond that.  The point of  this  argument
202       is  that  the  definition  of  the structure may change over time, with
203       additional fields  being  added  to  the  end.   This  argument  allows
204       pnm_readpaminit  to  distinguish  between  a  new program that wants to
205       exploit the additional features and an old program that  cannot  (or  a
206       new  program that just doesn't want to deal with the added complexity).
207       At a minimum, this size must contain the members up through tuple_type.
208       You  should  use  the  PAM_STRUCT_SIZE  macro to compute this argument.
209       E.g. PAM_STRUCT_SIZE(tuple_type).
210
211       PAM_STRUCT_SIZE was introduced in Netpbm 10.23 (July 2004).   In  older
212       Netpbm,  you  can  just use sizeof(), but then your code is not forward
213       compatible at the source code level with newer libnetpbm (because  when
214       you compile it with newer libnetpbm header files, you'll be saying your
215       structure contains all the new members that  have  been  invented,  but
216       your code doesn't actually initialize them).  So you might want to com‐
217       pute a proper size yourself.
218
219       The function expects to find the image file positioned to the start  of
220       the header and leaves it positioned to the start of the raster.
221
222       pnm_readpamrow()  reads  a  row of the raster from a Netpbm image file.
223       It expects all of the members of the *pamP structure  to  be  set  upon
224       invocation  and  does  not  modify any of them.  It expects to find the
225       file positioned to the start of the row in question in the  raster  and
226       leaves it positioned just after it.  It returns the row as the array of
227       tuples tuplerow, which must already have its column pointers set up  so
228       that it forms a C 2-dimensional array.  The leftmost tuple is Element 0
229       of this array.
230
231       pnm_readpam() reads an entire image from a PAM or PNM  image  file  and
232       allocates  the space in which to return the raster.  It expects to find
233       the file positioned to the first byte of the image and leaves it  posi‐
234       tioned just after the image.
235
236       *pamP is the same as for pnm_readpaminit().
237
238       The  return  value is a newly allocated array of the rows of the image,
239       with the top row being Element 0 of the array.  Each row is represented
240       as pnm_readpamrow() would return.
241
242       The  return  value  is also effectively a 3-dimensional C array of sam‐
243       ples, with the dimensions corresponding to the height, width, and depth
244       of the image, in that order.
245
246       pnm_readpam()  combines the functions of pnm_allocpamarray(), pnm_read‐
247       paminit(), and iterations of pnm_readpamrow().   It  may  require  more
248       dynamic storage than you can afford.
249
250       pnm_readpamrown()  is  like pnm_readpamrow() except that it returns the
251       row contents in normalized form (composed of normalized tuples (tuplen)
252       instead of basic form (tuple).
253
254       pnm_readpaminit()  and  pnm_readpam abort the program with a message to
255       Standard Error if the PAM or PNM  image  header  is  not  syntactically
256       valid,  including  if  it  contains  a number too large to be processed
257       using the system's normal data structures (to wit, a number that  won't
258       fit in a C 'int').
259
260
261   Writing Netpbm Files
262       Synopsis
263
264       void pnm_writepaminit( struct pam *pamP);
265
266       void pnm_writepamrow( struct pam *pamP, const tuple *tuplerow);
267
268       void pnm_writepam( struct pam *pamP, const tuple * const *tuplearray);
269
270       void pnm_writepamrown( struct pam *pamP, const tuplen *tuplerown);
271
272       void pnm_formatpamrow( struct pam *pamP, const tuple *tuplerow unsigned
273       char * const outbuf, unsigned int * const rowSizeP );
274
275       Description
276
277       pnm_writepaminit() writes the header of a PAM or PNM image and computes
278       some of the fields of the pam structure.
279
280       See above for a description of the pamP argument.
281
282       The  following  members of the *pamP structure must be set upon invoca‐
283       tion to tell the function how and what to write.  size, len, file, for‐
284       mat,  height, width, depth, maxval.  Furthermore, if format is PAM_FOR‐
285       MAT, tuple_type must be set and if format is not PAM_FORMAT,  plainfor‐
286       mat must be set.
287
288       pnm_writepaminit() sets the bytes_per_sample member based on the infor‐
289       mation supplied.
290
291       pnm_writepamrow() writes a row of the raster into a PAM  or  PNM  image
292       file.   It  expects  to  find  the file positioned where the row should
293       start and leaves it  positioned  just  after  the  row.   The  function
294       requires  all  the  elements  of  *pamP  to  be set upon invocation and
295       doesn't modify them.
296
297       tuplerow is an array of tuples  representing  the  row.   The  leftmost
298       tuple is Element 0 of this array.
299
300       pnm_writepam()  writes an entire PAM or PNM image to a PAM or PNM image
301       file.  It expects to find the file positioned to where the image should
302       start and leaves it positioned just after the image.
303
304       The  members of the *pamP structure that must be set up invocation, and
305       their meanings, is the same as for pnm_writepaminit.
306
307       pnm_writepam() sets the bytes_per_sample member based on  the  informa‐
308       tion supplied.
309
310       tuplearray   is   an  array  of  rows  such  that  you  would  pass  to
311       pnm_writepamrow(), with the top row being Element 0 of the array.
312
313       pnm_writepam() combines the functions of pnm_writepaminit(), and itera‐
314       tions  of pnm_writepamrow().  Its raster input may be more storage than
315       you can afford.
316
317       pnm_writepamrown() is like pnm_writepamrow() except that it  takes  the
318       row contents in normalized form (composed of normalized tuples (tuplen)
319       instead of basic form (tuple).
320
321       pnm_formatpamrow() is like pnm_writepamrow(), except  that  instead  of
322       writing  a row to a file, it places the same bytes that would go in the
323       file in a buffer you supply.  There isn't  an  equivalent  function  to
324       construct   an   image   header;   i.e.   there   is   no   analog   to
325       pnm_writepaminit().  But the header format, particularly for PAM, is so
326       simple  that  you  can easily build it yourself with standard C library
327       string functions.
328
329       pnm_formatpamrow() was new in Netpbm 10.25 (October 2004).
330
331
332   Transforming Pixels
333       Synopsis
334
335       void pnm_YCbCrtuple( tuple  tuple,  double  *YP,  double  *CrP,  double
336       *CbP);
337
338       void  pnm_YCbCr_to_rgbtuple( const struct pam * const pamP, tuple const
339       tuple, double const Y, double const Cb, double const Cr,  int  *  const
340       overflowP);
341
342       extern double pnm_lumin_factor[3];
343
344       void  pnm_normalizetuple(  struct  pam * const pamP, tuple        const
345       tuple, tuplen       const tuplen);
346
347       void pnm_unnormalizetuple( struct pam * const pamP, tuplen        const
348       tuplen, tuple        const tuple);
349
350       void  pnm_normalizeRow(  struct  pam  *       const pamP, const tuple *
351       const  tuplerow,  pnm_transformMap  *   const   transform,   tuplen   *
352       const tuplenrow);
353
354       void  pnm_unnormalizeRow( struct pam *       const pamP, const tuplen *
355       const  tuplenrow,  pnm_transformMap  *   const   transform,   tuple   *
356       const tuplerow);
357
358       void pnm_gammarown( struct pam * const pamP, tuplen *     const row);
359
360       void pnm_ungammarown( struct pam * const pamP, tuplen *     const row);
361
362       void  pnm_applyopacityrown( struct pam * const pamP, tuplen *     const
363       tuplenrow);
364
365       void  pnm_unapplyopacityrown(  struct  pam  *  const  pamP,  tuplen   *
366       const tuplenrow);
367
368       pnm_transformMap  *  pnm_creategammatransform( const struct pam * const
369       pamP);
370
371       void pnm_freegammatransform( const pnm_transformMap * const  transform,
372       const struct pam *       const pamP);
373
374       pnm_transformMap * pnm_createungammatransform( const struct pam * const
375       pamP);
376
377       void pnm_freeungammatransform( const pnm_transformMap  *  const  trans‐
378       form, const struct pam *       const pamP);
379
380
381       Description
382
383       pnm_YCbCrtuple()  returns the Y/Cb/Cr luminance/chrominance representa‐
384       tion of the color represented by the input  tuple,  assuming  that  the
385       tuple  is an RGB color representation (which is the case if it was read
386       from a PPM image).  The output components are based on the  same  scale
387       (maxval)  as  the  input  tuple,  but are floating point nonetheless to
388       avoid losing information because of rounding.  Divide them by the  max‐
389       val to get normalized [0..1] values.
390
391       pnm_YCbCr_to_rgbtuple()  does  the  reverse.  pamP indicates the maxval
392       for the returned tuple, and the Y, Cb, and Cr arguments are of the same
393       scale.
394
395       It  is  possible  for  Y, Cb, and Cr to describe a color that cannot be
396       represented in RGB form.  In that case, pnm_YCbCr_to_rgbtuple() chooses
397       a  color  as close as possible (by clipping each component to 0 and the
398       maxval) and sets *overflowP true.  It otherwise sets *overflowP false.
399
400
401       pnm_lumin_factor[] is the factors (weights) one  uses  to  compute  the
402       intensity  of  a  color  (according  to  some  standard -- I don't know
403       which).  pnm_lumin_factor[0] is for the red component, [1] is  for  the
404       green, and [2] is for the blue.  They add up to 1.
405
406       pnm_gammarown()  and  pnm_ungammarown() apply and unapply gamma correc‐
407       tion  to  a  row  of  an  image  using  the  same   transformation   as
408       pm_gamma709() and pm_ungamma709() ⟨libpm.html#gamma⟩ .  Note that these
409       operate on a row of normalized tuples (tuplen, not tuple).
410
411       pnm_applyopacityrown() reduces the intensity of samples  in  accordance
412       with  the  opacity plane of an image.  The opacity plane, if it exists,
413       tells how much of the light from that pixel should show when the  image
414       is  composed  with  another  image.   You use pnm_applyopacityrown() in
415       preparation for doing such a composition.  For example, if the  opacity
416       plane  says that the left half of the image is 50% opaque and the right
417       half 100% opaque, pnm_applyopacityrown() will reduce the  intensity  of
418       each sample of each tuple (pixel) in the left half of the image by 50%,
419       and leave the rest alone.
420
421       If the image does not have an opacity plane (i.e. its tuple type is not
422       one  that  libnetpbm recognizes as having an opacity plane), pnm_apply‐
423       opacityrown() does nothing (which  is  the  same  as  assuming  opacity
424       100%).  The tuple types that libnetpbm recognizes as having opacity are
425       RGB_ALPHA and GRAYSCALE_ALPHA.
426
427       pnm_unapplyopacityrown() does the reverse.  It assumes the  intensities
428       are  already reduced according to the opacity plane, and raises back to
429       normal.
430
431       pnm_applyopacityrown() works on (takes as input and produces as output)
432       normalized,  intensity-proportional  tuples.  That means you will typi‐
433       cally read the row from the image file with pnm_readpamrown() and  then
434       gamma-correct  it with pnm_ungammarown(), and then do pnm_applyopacity‐
435       rown().  You then manipulate the row further (perhaps add it with other
436       rows  you've  processed  similarly),  then do pnm_unapplyopacityrown(),
437       then pnm_gammarown(), then pnm_writepamrown().
438
439       pnm_applyopacityrown() and pnm_unapplyopacityrown() were new in  Netpbm
440       10.25 (October 2004).
441
442       pnm_normalizetuple() and pnm_unnormalizetuple() convert between a tuple
443       data type and a tuplen data type.  The former represents a sample value
444       using  the  same  unsigned  integer that is in the PAM image, while the
445       latter represents a sample value as a number scaled by  the  maxval  to
446       the  range  0..1.  I.e. pnm_normalizetuple() divides every sample value
447       by the maxval and pnm_unnormalizetuple() multiples every sample by  the
448       maxval.
449
450       pnm_normalizeRow()  and  pnm_unnormalizeRow()  do  the same thing on an
451       entire tuple row, but also have an extra feature:  You  can  specify  a
452       transform  function  to  be  applied in addition.  Typically, this is a
453       gamma transform function.  You can of course  more  easily  apply  your
454       transform  function  separately  from  normalizing, but doing it all at
455       once is usually way faster.  Why?  Because you can use a  lookup  table
456       that is indexed by an integer on one side and produces a floating point
457       number on the other.  To do it separately,  you'd  either  have  to  do
458       floating  point  arithmetic on the normalized value or do the transform
459       on the integer values and lose a lot of precision.
460
461       If you don't have any transformation to apply, just  specify  NULL  for
462       the  transform  argument  and  the  function  will just normalize (i.e.
463       divide or multiply by the maxval).
464
465       Here's an example of doing a transformation.  The example composes  two
466       images  together,  something  that has to be done with intensity-linear
467       sample values.
468
469
470       pnm_transformMap * const transform1 = pnm_createungammatransform(&inpam1);
471       pnm_transformMap * const transform2 = pnm_createungammatransform(&inpam2);
472       pnm_transformMap * const transformOut = pnm_creategammatransform(&outpam);
473
474       pnm_readpamrow(&inpam1, inrow1);
475       pnm_readpamrow(&inpam2, inrow2);
476
477       pnm_normalizeRow(&inpam1, inrow1, transform1, normInrow1);
478       pnm_normalizeRow(&inpam2, inrow2, transform2, normInrow2);
479
480       for (col = 0; col < outpam.width; ++col)
481           normOutrow[col] = (normInrow1[col] + normInrow2[col])/2;
482
483       pnm_unnormalizeRow(&outpam, normOutrow, transformOut, outrow);
484
485       pnm_writepamrow(&outpam, outrow);
486
487
488       To specify a transform, you  must  create  a  special  pnm_transformMap
489       object  and  pass it as the transform argument.  Typically, your trans‐
490       form is a gamma transformation because you want to work  in  intensity-
491       proportional sample values and the PAM image format uses gamma-adjusted
492       ones.  In that case, just use pnm_creategammatransform() and  pnm_crea‐
493       teungammatransform() to create this object and don't worry about what's
494       inside it.
495
496       pnm_creategammatransform()  and   pnm_createungammatransform()   create
497       objects  that  you use with pnm_normalizeRow() and pnm_unnormalizeRow()
498       as described above.  The created  object  describes  a  transform  that
499       applies  or  reverses  the ITU-R Recommendation BT.709 gamma adjustment
500       that is used in PAM visual images and normalizes  or  unnormalizes  the
501       sample values.
502
503       pnm_freegammatransform()  and  pnm_freeungammatransform()  destroy  the
504       objects.
505
506
507
508   Miscellaneous
509       Synopsis
510
511       void  pnm_checkpam(  struct  pam  *pamP,   const   enum   pm_check_type
512       check_type, enum pm_check_code *retvalP);
513
514       void pnm_nextimage( FILE *file, int * const eofP);
515
516       Description
517
518       pnm_checkpam()  checks  for  the  common file integrity error where the
519       file is the wrong size to contain the raster, according to the informa‐
520       tion in the header.
521
522       pnm_nextimage()positions a Netpbm image input file to the next image in
523       it (so that a subsequent pnm_readpaminit() reads its header).
524

DOCUMENT SOURCE

526       This manual page was generated by the Netpbm tool 'makeman'  from  HTML
527       source.  The master documentation is at
528
529              http://netpbm.sourceforge.net/doc/libnetpbm_image.html
530
531netpbm documentation             December 2L0i0b3netpbm Image Processing Manual(3)
Impressum