1 /*=============================================================================
2 These are declarations for use with the Portable Arbitrary Map (PAM)
3 format and the Netpbm library functions specific to them.
4
5 This file was originally written by Bryan Henderson and is contributed
6 to the public domain by him and subsequent authors.
7 =============================================================================*/
8 #ifndef PAM_H
9 #define PAM_H
10
11 #include <netpbm/pm_config.h>
12 #include <netpbm/pm.h>
13 #include <netpbm/pnm.h>
14
15 #ifdef __cplusplus
16 extern "C" {
17 #endif
18 #if 0
19 } /* to fake out automatic code indenters */
20 #endif
21
22 typedef unsigned long sample;
23 /* Regardless of the capacity of "unsigned long", a sample is always
24 less than 1 << 16. This is essential for some code to avoid
25 arithmetic overflows.
26 */
27
28 struct pam {
29 /* This structure describes an open PAM image file. It consists
30 entirely of information that belongs in the header of a PAM image
31 and filesystem information. It does not contain any state
32 information about the processing of that image.
33
34 This is not considered to be an opaque object. The user of Netbpm
35 libraries is free to access and set any of these fields whenever
36 appropriate. The structure exists to make coding of function calls
37 easy.
38 */
39
40 /* 'size' and 'len' are necessary in order to provide forward and
41 backward compatibility between library functions and calling programs
42 as this structure grows.
43 */
44 unsigned int size;
45 /* The storage size of this entire structure, in bytes */
46 unsigned int len;
47 /* The length, in bytes, of the information in this structure.
48 The information starts in the first byte and is contiguous.
49 This cannot be greater than 'size'
50
51 Use PAM_STRUCT_SIZE() to compute or interpret a value for this.
52 */
53 FILE * file;
54 int format;
55 /* The format code of the image. This is PAM_FORMAT
56 unless the PAM image is really a view of a PBM, PGM, or PPM
57 image. Then it's PBM_FORMAT, RPBM_FORMAT, etc. For output,
58 only the format _type_ is significant, e.g. PBM_FORMAT
59 and RPBM_FORMAT have identical effect. This is because on
60 output, 'plainformat' determines whether the output is the
61 raw or plain format of the type given by 'format'.
62 */
63 unsigned int plainformat;
64 /* Logical: On output, use plain version of the format type
65 indicated by 'format'. Otherwise, use the raw version.
66 (i.e., on output, the plainness information in 'format' is
67 irrelevant). Input functions set this to FALSE, for the
68 convenience of programs that copy an input pam structure for
69 use with output.
70
71 Before Netpbm 10.32, this was rather different. It simply
72 described for convenience the plainness of the format indicated
73 by 'format'.
74
75 This is meaningless when 'format' is PAM_FORMAT, as PAM does not
76 have plain and raw variations.
77 */
78 int height; /* Height of image in rows */
79 int width;
80 /* Width of image in number of columns (tuples per row) */
81 unsigned int depth;
82 /* Depth of image (number of samples in each tuple). */
83 sample maxval; /* Maximum defined value for a sample */
84 unsigned int bytes_per_sample;
85 /* Number of bytes used to represent each sample in the image file.
86 Note that this is strictly a function of 'maxval'. It is in a
87 a separate member for computational speed.
88 */
89 char tuple_type[256];
90 /* The tuple type string from the image header. If the PAM image
91 is really a view of a PBM, PGM, or PPM image, the value is
92 PAM_PBM_TUPLETYPE, PAM_PGM_TUPLETYPE, or PAM_PPM_TUPLETYPE,
93 respectively.
94 */
95 unsigned int allocation_depth;
96 /* The number of samples for which memory is allocated for any
97 'tuple' type associated with this PAM structure. This must
98 be at least as great as 'depth'. Only the first 'depth' of
99 the samples of a tuple are meaningful.
100
101 The purpose of this is to make it possible for a program to
102 change the type of a tuple to one with more or fewer
103 planes.
104
105 0 means the allocation depth is the same as the image depth.
106 */
107 const char ** comment_p;
108 /* Pointer to a pointer to a NUL-terminated ASCII string of
109 comments. When reading an image, this contains the
110 comments from the image's PAM header; when writing, the
111 image gets these as comments, right after the magic number
112 line. The individual comments are delimited by newlines
113 and are in the same order as in the PAM header.
114
115 On output, NULL means no comments.
116
117 On input, libnetpbm mallocs storage for the comments and places
118 the pointer at *comment_p. Caller must free it. NULL means
119 libnetpbm does not return comments and does not allocate any
120 storage.
121 */
122 int visual; /* boolean */
123 /* tuple_type is one of the PAM-defined tuple types for visual
124 images ("GRAYSCALE", "RGB_ALPHA", etc.).
125 */
126 unsigned int color_depth;
127 /* Number of color planes (i.e. 'depth', but without transparency).
128 The color planes are the lowest numbered ones. Meaningless if
129 'visual' is false.
130 */
131 int have_opacity; /* boolean */
132 /* The tuples have an opacity (transparency, alpha) plane.
133 Meaningless if 'visual' is false.
134 */
135 unsigned int opacity_plane;
136 /* The plane number of the opacity plane; meaningless if
137 'haveOpacity' is false or 'visual' is false.
138 */
139 };
140
141 #define PAM_HAVE_ALLOCATION_DEPTH 1
142 #define PAM_HAVE_COMMENT_P 1
143
144 /* PAM_STRUCT_SIZE(x) tells you how big a struct pam is up through the
145 member named x. This is useful in conjunction with the 'len' value
146 to determine which fields are present in the structure.
147 */
148
149 /* Some compilers are really vigilant and recognize it as an error
150 to cast a 64 bit address to a 32 bit type. Hence the roundabout
151 casting in PAM_MEMBER_OFFSET.
152 */
153 #define PAM_MEMBER_OFFSET(mbrname) \
154 ((size_t)(unsigned long)(char*)&((struct pam *)0)->mbrname)
155 #define PAM_MEMBER_SIZE(mbrname) \
156 sizeof(((struct pam *)0)->mbrname)
157 #define PAM_STRUCT_SIZE(mbrname) \
158 (PAM_MEMBER_OFFSET(mbrname) + PAM_MEMBER_SIZE(mbrname))
159
160 #define PAM_BLACK 0
161 #define PAM_BW_WHITE 1
162
163 #define PAM_PBM_TUPLETYPE "BLACKANDWHITE"
164 #define PAM_PGM_TUPLETYPE "GRAYSCALE"
165 #define PAM_PPM_TUPLETYPE "RGB"
166 #define PAM_PBM_ALPHA_TUPLETYPE "BLACKANDWHITE_ALPHA"
167 #define PAM_PGM_ALPHA_TUPLETYPE "GRAYSCALE_ALPHA"
168 #define PAM_PPM_ALPHA_TUPLETYPE "RGB_ALPHA"
169
170 #define PAM_PBM_BLACK PAM_BLACK
171 #define PAM_PBM_WHITE PAM_BW_WHITE
172 /* These are values of samples in a PAM image that represents a black
173 and white bitmap image. They are the values of black and white,
174 respectively. For example, if you use pnm_readpamrow() to read a
175 row from a PBM file, the black pixels get returned as
176 PAM_PBM_BLACK.
177 */
178
179 #define PAM_RED_PLANE 0
180 #define PAM_GRN_PLANE 1
181 #define PAM_BLU_PLANE 2
182 /* These are plane numbers for the 3 planes of a PAM image that
183 represents an RGB image (tuple type is "RGB"). So
184 if 'pixel' is a tuple returned by pnmreadpamrow(), then
185 pixel[PAM_GRN_PLANE] is the value of the green sample in that
186 pixel.
187 */
188 #define PAM_TRN_PLANE 3
189 /* A PAM with "RGB_ALPHA" tuple type has this 4th plane
190 for transparency. 0 = transparent, maxval = opaque.
191 */
192 #define PAM_GRAY_TRN_PLANE 1
193 /* For a "GRAYSCALE" tuple type, this is the transparency plane */
194
195 typedef sample *tuple;
196 /* A tuple in a PAM. This is an array such that tuple[i-1] is the
197 ith sample (element) in the tuple. It's dimension is the depth
198 of the image (see pam.depth above).
199 */
200
201 #define PAM_OVERALL_MAXVAL 65535
202
203 /* Note: xv uses the same "P7" signature for its thumbnail images (it
204 started using it years before PAM and unbeknownst to the designer
205 of PAM). But these images are still easily distinguishable from
206 PAMs
207 */
208 #define PAM_MAGIC1 'P'
209 #define PAM_MAGIC2 '7'
210 #define PAM_FORMAT (PAM_MAGIC1 * 256 + PAM_MAGIC2)
211 #define PAM_TYPE PAM_FORMAT
212
213 /* Macro for turning a format number into a type number. */
214
215 #define PAM_FORMAT_TYPE(f) ((f) == PAM_FORMAT ? PAM_TYPE : PPM_FORMAT_TYPE(f))
216
217 struct pamtuples {
218 struct pam * pamP;
219 tuple *** tuplesP;
220 };
221
222
223 typedef float * pnm_transformMap;
224 /* This is an array of transform maps. transform[N] is the
225 array that is the map for Plane N.
226
227 Transform maps define a transformation between PAM sample value
228 to normalized libnetpbm "samplen" value, i.e. what you get back
229 from pnm_readpamrown() or pass to pnm_writepamrown().
230 Typically, it's a gamma transfer function generated by
231 pnm_creategammatransform() or pnm_createungammatransform().
232
233 NULL for any transform means just plain normalization -- divide
234 the PAM sample value by the maxval to get the samplen, multiply
235 samplen by the maxval and round to get PAM sample value.
236
237 NULL for map table, or 'transform' member not present (pam
238 structure is too small to contain it) means ALL transforms
239 are plain normalization.
240
241 Each transform map is an array indexed by a PAM sample
242 value, containing 'float' values. So it must have 'maxval'
243 entries. The sample -> samplen transformation is just the
244 obvious table lookup. The samplen -> sample transformation is
245 more complicated -- if the samplen value is between map[N]
246 and map[N+1], then the sample value is N. And only transforms
247 where map[N+1] > map[N] are allowed.
248 */
249
250 /* Declarations of library functions. */
251
252 /* We don't have a specific PAM function for init and nextimage, because
253 one can simply use pnm_init() and pnm_nextimage() from pnm.h.
254 */
255
256 unsigned int
257 pnm_bytespersample(sample const maxval);
258
259 int
260 pnm_tupleequal(const struct pam * const pamP,
261 tuple const comparand,
262 tuple const comparator);
263
264 void
265 pnm_assigntuple(const struct pam * const pamP,
266 tuple const dest,
267 tuple const source);
268
269 static __inline__ sample
pnm_scalesample(sample const source,sample const oldmaxval,sample const newmaxval)270 pnm_scalesample(sample const source,
271 sample const oldmaxval,
272 sample const newmaxval) {
273
274 if (oldmaxval == newmaxval)
275 /* Fast path for common case */
276 return source;
277 else
278 return (source * newmaxval + (oldmaxval/2)) / oldmaxval;
279 }
280
281
282
283 void
284 pnm_scaletuple(const struct pam * const pamP,
285 tuple const dest,
286 tuple const source,
287 sample const newmaxval);
288
289 void
290 pnm_scaletuplerow(const struct pam * const pamP,
291 tuple * const destRow,
292 tuple * const sourceRow,
293 sample const newMaxval);
294
295 void
296 pnm_maketuplergb(const struct pam * const pamP,
297 tuple const tuple);
298
299 void
300 pnm_makerowrgb(const struct pam * const pamP,
301 tuple * const tuplerow);
302
303 void
304 pnm_makearrayrgb(const struct pam * const pamP,
305 tuple ** const tuples);
306
307 void
308 pnm_makerowrgba(const struct pam * const pamP,
309 tuple * const tuplerow);
310
311 void
312 pnm_addopacityrow(const struct pam * const pamP,
313 tuple * const tuplerow);
314
315 void
316 pnm_getopacity(const struct pam * const pamP,
317 int * const haveOpacityP,
318 unsigned int * const opacityPlaneP);
319
320 void
321 pnm_createBlackTuple(const struct pam * const pamP, tuple * const blackTupleP);
322
323 tuple
324 pnm_allocpamtuple(const struct pam * const pamP);
325
326 #define pnm_freepamtuple(tuple) pm_freerow((char*) tuple)
327
328 tuple *
329 pnm_allocpamrow(const struct pam * const pamP);
330
331 #define pnm_freepamrow(tuplerow) pm_freerow((char*) tuplerow)
332
333 tuple **
334 pnm_allocpamarray(const struct pam * const pamP);
335
336 void
337 pnm_freepamarray(tuple ** const tuplearray, const struct pam * const pamP);
338
339 void
340 pnm_setminallocationdepth(struct pam * const pamP,
341 unsigned int const allocationDepth);
342
343 void
344 pnm_setpamrow(const struct pam * const pam,
345 tuple * const tuplerow,
346 sample const value);
347
348 unsigned char *
349 pnm_allocrowimage(const struct pam * const pamP);
350
351 void
352 pnm_freerowimage(unsigned char * const rowimage);
353
354 void
355 pnm_readpaminit(FILE * const file,
356 struct pam * const pamP,
357 int const size);
358
359 void
360 pnm_readpamrow(const struct pam * const pamP, tuple* const tuplerow);
361
362 tuple **
363 pnm_readpam(FILE * const file,
364 struct pam * const pamP,
365 int const size);
366
367 void
368 pnm_writepaminit(struct pam * const pamP);
369
370 void
371 pnm_formatpamrow(const struct pam * const pamP,
372 const tuple * const tuplerow,
373 unsigned char * const outbuf,
374 unsigned int * const rowSizeP);
375
376 void
377 pnm_writepamrow(const struct pam * const pamP, const tuple * const tuplerow);
378
379 void
380 pnm_writepamrowmult(const struct pam * const pamP,
381 const tuple * const tuplerow,
382 unsigned int const rptcnt);
383
384 void
385 pnm_writepam(struct pam * const pamP, tuple ** const tuplearray);
386
387 void
388 pnm_checkpam(const struct pam * const pamP,
389 enum pm_check_type const checkType,
390 enum pm_check_code * const retvalP);
391
392 /*----------------------------------------------------------------------------
393 Facilities for working with maxval-normalized samples. Such samples
394 are floating point quantities in the range 0..1.
395
396 This is just a working format; there is no Netpbm image format that
397 has normalized samples.
398 -----------------------------------------------------------------------------*/
399 typedef float samplen;
400
401 typedef samplen *tuplen;
402 /* Same as 'tuple', except using normalized samples. */
403
404 tuplen
405 pnm_allocpamtuplen(const struct pam * const pamP);
406
407 #define pnm_freepamtuplen(tuplen) pm_freerow((char*) tuplen)
408
409 tuplen *
410 pnm_allocpamrown(const struct pam * const pamP);
411
412 #define pnm_freepamrown(tuplenrow) pm_freerow((char*) tuplenrow)
413
414 tuplen *
415 pnm_allocpamrown(const struct pam * const pamP);
416
417 void
418 pnm_readpamrown(const struct pam * const pamP,
419 tuplen * const tuplenrow);
420
421 void
422 pnm_writepamrown(const struct pam * const pamP,
423 const tuplen * const tuplenrow);
424
425 tuplen **
426 pnm_allocpamarrayn(const struct pam * const pamP);
427
428 void
429 pnm_freepamarrayn(tuplen ** const tuplenarray,
430 const struct pam * const pamP);
431
432 tuplen**
433 pnm_readpamn(FILE * const file,
434 struct pam * const pamP,
435 int const size);
436
437 void
438 pnm_writepamn(struct pam * const pamP,
439 tuplen ** const tuplenarray);
440
441 samplen
442 pnm_normalized_sample(struct pam * const pamP,
443 sample const sample);
444
445 sample
446 pnm_unnormalized_sample(struct pam * const pamP,
447 samplen const sampleVal);
448
449 void
450 pnm_normalizetuple(struct pam * const pamP,
451 tuple const tuple,
452 tuplen const tuplen);
453
454 void
455 pnm_unnormalizetuple(struct pam * const pamP,
456 tuplen const tuplen,
457 tuple const tuple);
458
459 void
460 pnm_normalizeRow(struct pam * const pamP,
461 const tuple * const tuplerow,
462 const pnm_transformMap * const transform,
463 tuplen * const tuplenrow);
464
465 void
466 pnm_unnormalizeRow(struct pam * const pamP,
467 const tuplen * const tuplenrow,
468 const pnm_transformMap * const transform,
469 tuple * const tuplerow);
470
471 /*----------------------------------------------------------------------------
472 Facilities for working with visual images in particular
473 -----------------------------------------------------------------------------*/
474
475
476 void
477 pnm_gammarown(struct pam * const pamP,
478 tuplen * const row);
479
480 void
481 pnm_ungammarown(struct pam * const pamP,
482 tuplen * const row);
483
484 void
485 pnm_applyopacityrown(struct pam * const pamP,
486 tuplen * const tuplenrow);
487
488 void
489 pnm_unapplyopacityrown(struct pam * const pamP,
490 tuplen * const tuplenrow);
491
492 void
493 pnm_maketuplergbn(const struct pam * const pamP,
494 tuplen const tuple);
495
496 void
497 pnm_makerowrgbn(const struct pam * const pamP,
498 tuplen * const tuplerow);
499
500 void
501 pnm_makearrayrgbn(const struct pam * const pamP,
502 tuplen ** const tuples);
503
504 pnm_transformMap *
505 pnm_creategammatransform(const struct pam * const pamP);
506
507 void
508 pnm_freegammatransform(const pnm_transformMap * const transform,
509 const struct pam * const pamP);
510
511 pnm_transformMap *
512 pnm_createungammatransform(const struct pam * const pamP);
513
514 #define pnm_freeungammatransform pnm_freegammatransform;
515
516 tuple
517 pnm_parsecolor2(const char * const colorname,
518 sample const maxval,
519 int const closeOk);
520
521 tuple
522 pnm_parsecolor(const char * const colorname,
523 sample const maxval);
524
525 tuplen
526 pnm_parsecolorn(const char * const colorname);
527
528 const char *
529 pnm_colorname(struct pam * const pamP,
530 tuple const color,
531 int const hexok);
532
533 const char *
534 pnm_colorspec_rgb_integer(struct pam * const pamP,
535 tuple const color,
536 sample const maxval);
537
538 const char *
539 pnm_colorspec_rgb_norm(struct pam * const pamP,
540 tuple const color,
541 unsigned int const digitCt);
542
543 const char *
544 pnm_colorspec_rgb_x11(struct pam * const pamP,
545 tuple const color,
546 unsigned int const hexDigitCt);
547
548 const char *
549 pnm_colorspec_dict(struct pam * const pamP,
550 tuple const color);
551
552 const char *
553 pnm_colorspec_dict_close(struct pam * const pamP,
554 tuple const color);
555
556 extern double
557 pnm_lumin_factor[3];
558
559 void
560 pnm_YCbCrtuple(const tuple tuple,
561 double * const YP, double * const CbP, double * const CrP);
562
563 void
564 pnm_YCbCr_to_rgbtuple(const struct pam * const pamP,
565 tuple const tuple,
566 double const Y,
567 double const Cb,
568 double const Cr,
569 int * const overflowP);
570
571 #define pnm_rgbtupleisgray(tuple) \
572 ((tuple)[PAM_RED_PLANE] == (tuple)[PAM_GRN_PLANE] && \
573 (tuple)[PAM_RED_PLANE] == (tuple)[PAM_BLU_PLANE])
574
575 tuple
576 pnm_backgroundtuple(struct pam * const pamP,
577 tuple ** const tuples);
578
579 /*----------------------------------------------------------------------------
580 These are meant for passing to pm_system() as Standard Input feeder
581 and Standard Output accepter.
582
583 The 'feederParm' or 'accepterParm' is a pointer to a struct pamtuples.
584 -----------------------------------------------------------------------------*/
585
586 void
587 pm_feed_from_pamtuples(int const pipeToFeedFd,
588 void * const feederParm);
589
590 void
591 pm_accept_to_pamtuples(int const pipeToSuckFd,
592 void * const accepterParm);
593
594 #ifdef __cplusplus
595 }
596 #endif
597 #endif
598