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), PGMFunctionManual(1),
18       PPMFunctionManual(1),and   PNMFunctionManual(1).Notethatyoudonot   need
19       those  functions  to  process PBM, PGM, PPM, and PNM images.  The func‐
20       tions in this manual are sufficient for that.
21
22       The PPM drawing functions are covered separately in PPMDrawingFunction‐
23       Manual(1).
24
25       For introductory and general information using libnetpbm, see Libnetpb‐
26       mUser'sGuide(1).
27
28       libnetpbm also contains functions that are  not  specifically  oriented
29       toward  processing image data.  Read about those in the LibnetpbmUtili‐
30       tyManual(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) intead of regular samples (sample).
61
62
63
64       The main argument to most of the PAM functions is the address of a  pam
65       structure, which is defined as follows:
66
67       struct pam { int size int len FILE *file int format int plainformat int
68       height int width int depth  sample  maxval  int  bytes_per_sample  char
69       tuple_type[256] int allocation_depth char **comment_p; }
70
71       See The Libnetbm User's Guide ⟨libnetpbm_ug.html#pamstruct⟩  for infor‐
72       mation on the pam structure.
73
74
75

Macros

77       PNM_MAXMAXVAL is the maximum maxval that Netpbm images  could  histori‐
78       cally  have:  255.   Many  programs  aren't  capable of handling Netpbm
79       images with a maxval larger than this.  It's named this way  for  back‐
80       ward  compatibility  --  it  had this name back when it was the maximum
81       maxval.
82
83       PNM_OVERALLMAXVAL is the maximum maxval that  Netpbm  images  can  have
84       today (65535).
85
86       PBM_FORMAT, RPBM_FORMAT, PGM_FORMAT, RPGM_FORMAT, PPM_FORMAT, RPPM_FOR‐
87       MAT, and PAM_FORMAT are the format codes of the various Netpbm formats.
88       RPBM_FORMAT  is the raw PBM format and PBM_FORMAT is the plain PBM for‐
89       mat,  and  so  on.   See  the  format  member  of  the  pam   structure
90       ⟨libnetpbm_ug.html#pamstruct⟩ .
91
92       PAM_FORMAT_TYPE(format)  gives  the  type of a format, given the format
93       code.  The types of formats are PBM, PGM, PPM, and PAM and  macros  for
94       the  type  codes  are,  respectively, PBM_TYPE, PGM_TYPE, PPM_TYPE, and
95       PAM_TYPE.  Note that there are more format codes then there are  format
96       types  because  there  are different format codes for the plain and raw
97       subformats of each format.
98
99
100
101

Functions

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