1Libnetpbm Image Processing MLainburaalr(y3)FunctionLsibMnaentupablm Image Processing Manual(3)
2
3
4
5 Table Of Contents ⟨#toc⟩
6
8 libnetpbm_image - overview of netpbm image-processing functions
9
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
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
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
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
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)