1Pamtris User Manual(0) Pamtris User Manual(0)
2
3
4
6 pamtris - triangle rasterizer featuring perspective-correct interpola‐
7 tion of generic vertex attributes and depth buffering
8
9
11 pamtris
12
13 -width=width
14
15 -height=height
16
17 { -num_attribs=attributes_per_vertex [ -tupletype=tupletype ] | -rgb |
18 -grayscale }
19
20 [ -maxval=maxval ]
21
22 All options can be abbreviated to their shortest unique prefix. You
23 may use two hyphens instead of one to designate an option. You may use
24 either white space or an equals sign between an option name and its
25 value.
26
27
29 This program is part of Netpbm(1).
30
31 pamtris can be used to draw a great variety of 2D and 3D graphics by
32 composing arbitrarily complex pictures out of separate triangles, tri‐
33 angle strips and triangle fans. The program reads instructions written
34 in a simple command script notation from Standard Input and outputs its
35 results as a (potentially multi-image) PAM stream on Standard Output.
36
37 For example, the following input
38
39
40 mode fan
41 attribs 0 128 0
42 vertex 0 0 1
43 attribs 0 0 128
44 vertex 200 0 1
45 attribs 50 20 103
46 vertex 190 61 1
47 attribs 100 40 78
48 vertex 161 117 1
49 attribs 150 60 53
50 vertex 117 161 1
51 attribs 200 80 28
52 vertex 61 190 1
53 attribs 250 100 3
54 vertex 0 200 1
55 print
56
57
58
59
60 produces this:
61
62 Example pamtris output for FAN mode
63
64
65 The input file gives triangle data by setting the appropriate drawing
66 mode, if necessary, and then providing a list of vertices. Each vertex
67 is also associated with a list of up to 20 "attributes," which are in‐
68 teger values between 0 and a given maxval. In the most common usage,
69 you use pamtris to draw a visual image and a vertex has three at‐
70 tributes, which are an RGB specification of a color. Such attribute
71 lists may be provided on a per-vertex basis.
72
73 Prior to effectively writing a PAM image to Standard Output, pamtris
74 first rasterizes it onto an internal frame buffer, which consists of an
75 "image buffer" and a "depth buffer." The image buffer consists of a se‐
76 quence of height rows containing a sequence of width tuples. There is
77 one sample for each vertex attribute in every tuple plus an opacity
78 (alpha) sample. Each tuple in the image buffer is also associated with
79 an integer depth in the depth buffer, which determines whether subse‐
80 quent drawing operations affect that particular tuple or not. This pro‐
81 vides a way of depth-sorting graphical objects which is adequate for
82 many purposes in 2D and 3D computer graphics. One prominent shortcoming
83 of such an approach to depth-sorting, however, is that it does not au‐
84 tomatically work with objects which are intended to appear "translu‐
85 cent," therefore requiring more elaborate strategies to incorporate
86 said objects into pictures generated using this technique.
87
88 The opacity sample is the last sample of the tuple. pamtris manipu‐
89 lates opacity internally and for any tuple it is always either 0 or the
90 maxval. The program does not provide the user direct control over the
91 alpha image plane.
92
93 pamtris rasterizes triangles by approximating their visible area as a
94 collection of tuples at particular positions in the frame buffer, and
95 to each sample of every such tuple it assigns a value which is a per‐
96 spective-correct interpolation between the values of the corresponding
97 attribute for each vertex of the triangle. Whenever a tuple within the
98 area of the frame buffer is produced, it is written to the correspond‐
99 ing position in the frame buffer if and only if it passes a depth test.
100 This test works as follows: the depth value of every incoming tuple
101 (which is itself an interpolation between the Z-coordinates of the ver‐
102 tices of the corresponding triangle) is compared against the value in
103 the corresponding position in the depth buffer. If the depth value of
104 the incoming tuple equals or is smaller than the depth value already
105 present in said position in the depth buffer, the following happens.
106
107
108
109 • Every sample i, where 0 ≤ i < num_attribs, of the tuple in
110 the corresponding position in the image buffer is set to equal
111 the value of the respective sample of the incoming tuple; and
112 the alpha sample (the last one) is updated to the maxval;
113
114
115 • The depth value in the corresponding position in the depth buf‐
116 fer is updated to a depth value directly proportional to that of
117 the incoming tuple.
118
119
120 Otherwise, that particular tuple effects no change at all in the frame
121 buffer.
122
123 The frame buffer is initially set so that all samples in every tuple of
124 the image buffer contain the value 0, and all entries in the depth buf‐
125 fer contain the maximum permitted depth value.
126
127 The attributes' values, and therefore the samples in the output PAM im‐
128 ages, have no fixed interpretation ascribed to them (except for the
129 last image plane, which is deliberately supposed to represent tuple
130 opacity information); one may ascribe any suitable meaning to them,
131 such as that of colors, texture coordinates, surface normals, light in‐
132 teraction characteristics, texture influence coefficients for multi-
133 texturing, etc.
134
135
136
138 Fan Mode
139 The following command generates the image from the fan mode example at
140 the top of the DESCRIPTION ⟨#description⟩ section. If the file
141 fan.tris contains that code, you could process it with:
142
143
144 $ pamtris -height=200 -width=200 -rgb <fan.tris >fan.pam
145
146
147
148
149 Strip Mode
150 The following is an example of strip mode:
151
152
153 mode strip
154 attribs 255 0 0 # red
155 vertex 0 200 1
156 vertex 50 0 1
157 attribs 0 0 0 # black
158 vertex 100 200 1
159 attribs 0 205 205 # cyan
160 vertex 150 0 1
161 attribs 0 0 255 # blue
162 vertex 200 200 1
163 vertex 250 0 1
164 print
165
166
167
168 Save the above code in a file named strip.tris (for instance) and
169 process it with:
170
171
172 $ pamtris -height=200 -width=200 -rgb <strip.tris >strip.pam
173
174
175
176 to yield:
177
178 Example pamtris output for STRIP mode
179
180
181 Triangle Mode
182 The following is an example of triangle mode:
183
184
185 # yellow square
186 mode strip
187 attrib 155 155 0
188 vertex 50 50 100
189 vertex 50 200 100
190 vertex 200 50 100
191 vertex 200 200 100
192
193 # blue triangle
194 mode triangles
195 attrib 0 205 205
196 vertex 20 125 70
197 attrib 0 0 140
198 vertex 230 70 120 # Change "120" and see what happens
199 vertex 230 180 120 #
200 print
201
202
203
204 Save the above code in a file named pierce.tris (for instance) and
205 process it with:
206
207
208 $ pamtris -height=200 -width=200 -rgb <pierce.tris >pierce.pam
209
210
211
212 to yield:
213
214 Example pamtris output for TRIANGLES mode
215
216
217
218 Meta-programming
219 The pamtris command language is much too rudimentary to be used di‐
220 rectly for any serious drawing; you will probably want to use a general
221 purpose programming language to generate a temporary pamtris command
222 file.
223
224 For example, the draw_polygon procedure in the C program below outputs
225 pamtris instructions to draw a regular polygon. It does this by gener‐
226 ating a number of vertex instructions tracing around the perimeter of
227 the corresponding circumscribed circle. (Note: The PAM image produced
228 by piping the output of the below program into pamtris was subsequently
229 downscaled through pamscale -linear -xscale 0.25 -yscale 0.25 to
230 achieve an anti-aliased ⟨#antialias⟩ effect.)
231
232 Regular Polygons
233
234 /* ----------------------- *
235 * width = 512 *
236 * height = 512 *
237 * num_attribs = 3 *
238 * tupletype = RGB_ALPHA *
239 * ----------------------- */
240
241 #include <math.h>
242 #include <stdio.h>
243 #include <stdlib.h>
244
245 #define PI 3.14159265358979323844
246
247 void draw_polygon
248 (int const center_x, int const center_y, int const radius, int const sides)
249 {
250 printf("mode fan\n"
251 "vertex %d %d 0\n", center_x, center_y);
252
253 for(int i = 0; i <= sides; i++)
254 {
255 int const x = round(center_x + radius * cos(i*2.0*PI / sides));
256 int const y = round(center_y - radius * sin(i*2.0*PI / sides));
257
258 printf("vertex %d %d 0\n", x, y);
259 }
260 }
261
262 int main(void)
263 {
264 puts("attribs 0 185 80"); /* color: green */
265 draw_polygon(300, 210, 150, 5); /* draws pentagon */
266
267 puts("attribs 255 15 240"); /* color: magenta */
268 draw_polygon(150, 320, 100, 7); /* draws heptagon */
269
270 puts("!");
271 }
272
273
274
276 In addition to the options common to all programs based on libnetpbm
277 (most notably -quiet, see
278 Common Options ⟨index.html#commonoptions⟩ ), pamtris recognizes the
279 following command line options:
280
281 <dl compact="compact">
282
283 -width=width
284 Sets the width of the internal frame buffer and, by extension,
285 of the output PAM images, given in number of columns. This must
286 be an integer in the closed range [1, 8192].
287
288 This option is mandatory.
289
290
291 -height=height
292 This is the height of the internal frame buffer and, by exten‐
293 sion, of the output PAM images, given in number of rows. This
294 must be an integer in the closed range [1, 8192].
295
296 This option is mandatory.
297
298
299 -num_attribs=attributes_per_vertex
300 This is the number of attributes per vertex. The depth of the
301 output PAM images equals this value plus one (to accomodate the
302 alpha plane). The argument must be an integer in the closed
303 range [1, 20].
304
305 The input instruction stream may override this with a reset com‐
306 mand.
307
308 You must specify exactly one of -num_attribs, -rgb, and
309 -grayscale.
310
311
312
313 -tupletype=tupletype
314 This is the tuple type for the output PAM images. The argument
315 is a string which may be no longer than 255 characters.
316
317 The input instruction stream may override this with a reset com‐
318 mand.
319
320 The default is a null string.
321
322 This option cannot be specified together with -rgb or
323 -grayscale.
324
325
326
327
328 -rgb This is a convenience option which simply serves as an alias for
329 -num_attribs=3 -tupletype=RGB_ALPHA. In other words, this option
330 is a quick way to specify that you are going to use pamtris to
331 draw RGB(_ALPHA) color images directly, and the three vertex at‐
332 tributes are the red, green and blue levels of the color associ‐
333 ated with the vertex, in that order.
334
335 The input instruction stream may override this with a reset com‐
336 mand.
337
338 You must specify exactly one of -num_attribs, -rgb, and
339 -grayscale.
340
341 This option was new in Netpbm 10.85 (December 2018).
342
343
344 -grayscale
345 Another convenience option, similar to -rgb; except this one is
346 an alias for -num_attribs=1 -tupletype=GRAYSCALE_ALPHA. The one
347 vertex attribute is the gray level associated with the vertex.
348
349 The input instruction stream may override this with a reset com‐
350 mand.
351
352 You must specify exactly one of -num_attribs, -rgb, and
353 -grayscale.
354
355 This option was new in Netpbm 10.85 (December 2018).
356
357
358 -maxval=maxval
359 Sets the maxval of the output PAM images, which is also the max‐
360 imum permitted value for each vertex attribute. This must be an
361 integer in the closed range [1, 65535].
362
363 The default value is 255.
364
365 The input instruction stream may override this with a reset com‐
366 mand.
367
368
369
370
372 The input for pamtris consists of a stream of text lines read from
373 Standard Input.
374
375 Empty lines or lines that contain only white space characters are
376 called blank lines and are ignored.
377
378 When a # occurs anywhere in a line, pamtris ignores it along with every
379 character after it. In other words, everything from the # until the end
380 of the line receives the same treatment as white space.
381
382 Lines which are not blank must contain a sequence of strings, called
383 tokens, separated by white space. The first such token must be one of
384 the commands recognized by pamtris, and all further tokens are inter‐
385 preted as the arguments for that command, if it takes any. When an in‐
386 sufficient number of arguments is provided for a command, the line is
387 considered invalid and is given the same treatment as a blank line. The
388 same happens when an out of range argument or one of a kind different
389 of what is expected is given (for example, when you give a string of
390 letters where a numerical value is expected), or when an unrecognized
391 command/argument is found. When a number of arguments greater than that
392 required for a particular command is provided, only the portion of the
393 line up to the last required argument is considered and any further to‐
394 kens are ignored.
395
396 pamtris is case-insensitive. That is, mode, MODE, mODe, etc. are all
397 treated the same way.
398
399 The commands recognized by pamtris are:
400
401
402 mode
403
404 attribs
405
406 vertex
407
408 print
409
410 clear
411
412 reset
413
414 quit
415
416
417 You may use a minimum unique abbreviation of a command name. You may
418 use an exclamation mark (!) in place of the print command name and an
419 asterisk (*) in place of clear.
420
421 The functions of the commands are as follows.
422
423
424
425 mode { triangles | strip | fan }
426
427 This makes pamtris enter a new drawing mode. The argument is a
428 word which specifies the mode to change to. Instead of a full
429 argument name, it is permissible to provide a minimum unique ab‐
430 breviation, which has the same effect. The drawing mode will re‐
431 main the same until the next mode command is given.
432
433 This command also resets the current vertex list, which is
434 (re)initialized to an empty state after the command is executed.
435 One may add new vertices to this list through successive invoca‐
436 tions of the vertex command (see below). You do not have to
437 worry about providing "too many" vertices, since the vertex list
438 is virtualized: pamtris maintains only the state pertaining to
439 three vertices at any one time. The current vertex list is ini‐
440 tially empty.
441
442 It is permissible to give pamtris a mode command which instructs
443 it to enter a drawing mode it is currently already in. One might
444 use this approach to reset the current vertex list without
445 changing the current drawing mode.
446
447 Regardless of the current drawing mode, the program immediately
448 rasterizes a new triangle into the frame buffer as soon as you
449 provide the necessary vertices for it through the current vertex
450 list. (If you reset the vertex list before giving all the ver‐
451 tices necessary to draw a new triangle, the program effectively
452 discards from the list any vertices that might have been pushed
453 into the vertex list up to that point without using them to draw
454 any new triangles.)
455
456 In the following descriptions of each drawing mode, triangles'
457 and vertices' indices (ordinal numbers) are 0-based.
458
459 The triangles argument instructs pamtris to enter the "TRIAN‐
460 GLES" drawing mode. While in this mode, a series of separate
461 triangles is constructed. Every three vertices pushed into the
462 current vertex list specify a new triangle. Formally, this
463 means that every Nth triangle is specified by vertices 3*N,
464 3*N + 1, and 3*N + 2. This is the default initial mode and is
465 therefore not required to be set explicitly before drawing any
466 triangles.
467
468 The strip argument instructs pamtris to enter the "STRIP" draw‐
469 ing mode. While in this mode, pamtris constructs a "triangle
470 strip." That is, the first three vertices pushed into the cur‐
471 rent vertex list specify the first triangle, and every new ver‐
472 tex pushed after that specifies, together with the previous two,
473 the next triangle. Formally, this means that every Nth triangle
474 is specified by vertices N, N + 1, and N + 2.
475
476 The fan argument instructs pamtris to enter the "FAN" drawing
477 mode. While in this mode, a so-called "triangle fan" is con‐
478 structed. That is, the first three vertices pushed into the
479 current vertex list specify the first triangle, and every new
480 vertex pushed after that specifies, together with the previous
481 vertex and the first one, the next triangle. Formally, this
482 means that every Nth triangle is specified by vertices 0, N + 1,
483 and N + 2.
484
485
486
487
488 attribs a<sub>0 a<sub>1
489 a<sub>2 ... a<sub>num_attribs - 1
490
491 This updates the current attribute values list. This command
492 takes as arguments a sequence of num_attribs integers which rep‐
493 resent the values of the attributes to be associated with the
494 next vertex. This sequence of values is the just mentioned "cur‐
495 rent attribute values list."
496
497 Each ith argument, where 0 ≤ i < num_attribs, indicates
498 the value to be assigned to the ith attribute of the current at‐
499 tribute values list. All arguments must be integer values in the
500 closed range [0, maxval]. If a number of arguments less than
501 the current value of num_attribs is given, the command is con‐
502 sidered invalid and is therefore ignored.
503
504 The current attribute values list remains unchanged until the
505 next valid attribs or reset command is given. The attribs com‐
506 mand allows one to change the values of each attribute individu‐
507 ally, while the reset command is not specifically designed for
508 that function, but it has the side effect of setting all values
509 in the current attribute values list to the maxval (see below).
510
511 All values in the current attribute values list are initially
512 set to the maxval.
513
514 <dt id="cmd_vertex">vertex x y z [w]
515
516 Adds a new vertex to the current vertex list (see the mode com‐
517 mand above), assigning the values of the arguments to its re‐
518 spective coordinates, and the values in the current attribute
519 values list (see the attribs command above) to the respective
520 entries in the attribute list associated with the vertex.
521
522 x, y and z must be integer values in the closed range [-32767,
523 32767]. x and y represent, respectively, the column and row of
524 the tuple which corresponds to the location of the vertex. Such
525 values may correspond to tuples outside the limits of the frame
526 buffer. The origin of the coordinate system is at the top-left
527 tuple of the frame buffer. The X-axis goes from left to right,
528 and the Y-axis from top to bottom. A negative value for x indi‐
529 cates a column that many tuples to the left of the leftmost col‐
530 umn of the frame buffer. Likewise, a negative value for y indi‐
531 cates a row that many tuples above the uppermost row of the
532 frame buffer. Observe that those coordinates correspond directly
533 to a particular point in the coordinate system delineated above,
534 regardless of whether you are trying to draw an image which is
535 supposed to look as if viewed "in perspective" or not; pamtris
536 does not "warp" the coordinates you give in any way. Therefore,
537 if you want to draw images in perspective, you must compute val‐
538 ues for x and y already projected into pamtris' coordinate sys‐
539 tem yourself, using an external perspective projection method,
540 prior to giving them to the program.
541
542 The z parameter represents the Z-coordinate of the vertex,
543 which is used to compute depth values for tuples within the ar‐
544 eas of rasterized triangles. Intuitively, smaller values for z
545 mean "closer to the viewer," and larger ones mean "farther away
546 from the viewer" (but remember: as said above, the x and y coor‐
547 dinates are not warped in any way, which implies that they are
548 not affected by z; neither by the next parameter, for that mat‐
549 ter).
550
551 Optionally, you may provide a w parameter which represents a
552 "perspective correction factor" used to properly interpolate
553 vertex attributes across the area of the corresponding triangle.
554 This must be an integer value in the closed range [1, 1048575].
555 If you don't provide a value for it, the default value of 1 is
556 used (hence, if you want to nullify the effects of perspective
557 correction on a triangle so the output samples are computed as
558 if just linearly interpolated, simply do not provide a value for
559 w for any vertex of the triangle). If, however, you intend to
560 draw 3D geometry in perspective, you must provide an appropriate
561 value for this parameter, otherwise the output images might look
562 very wrong. w was new in Netpbm 10.85 (December 2018).
563
564 Consider the
565 typical model ⟨https://en.wikipedia.org/wiki/Viewing_frustum⟩
566 of the so-called "viewing frustum" used to project vertices in
567 3D "world space" onto a planar "image space." If we adopt the
568 convention that a "z-plane" means any plane parallel to the
569 view-plane (a.k.a. picture plane, a.k.a. near plane), the value
570 of w for a vertex should then be the (smallest/euclidean/orthog‐
571 onal) distance in pixels between the projection reference point
572 (PRP, or "eye") and the z-plane containing the vertex. One way
573 to compute this value amounts to simply taking the dot product
574 between the 3D vector r and the 3D unit vector n, where r is the
575 vector which goes from the projection reference point (PRP, or
576 "eye") to the vertex, and n is a view-plane normal (VPN) of unit
577 length which points away from the PRP. In other words, this is
578 equal to the length of the orthogonal projection of r on the
579 line "determined" by n.
580
581 (Note: For any two 3D vectors a and b, with respective real
582 scalar components a<sub>x, a<sub>y, a<sub>z and b<sub>x,
583 b<sub>y, b<sub>z, the dot product between a and b is simply
584 a<sub>x*b<sub>x + a<sub>y*b<sub>y + a<sub>z*b<sub>z.)
585
586
587
588 print
589
590 This writes a PAM image to Standard Output whose raster is a
591 copy of the current contents of the image buffer. The values of
592 the WIDTH and HEIGHT fields are the same as the width and
593 height, respectively, of the frame buffer, which were given on
594 the command line during program invocation. The MAXVAL field is
595 equal to the current maxval; the DEPTH field is equal to the
596 current value of num_attribs + 1; and the TUPLTYPE field is
597 equal to the current tupletype.
598
599 This command has no effect upon the current drawing state. E. g.
600 it does not modify the current drawing mode, the current vertex
601 list, etc.
602
603 One may issue an arbitrary number of print commands at different
604 positions in the input instruction sequence to produce a multi-
605 image PAM stream.
606
607
608 clear [ image | depth ]
609
610 Clears the frame buffer. That is, all samples in the image buf‐
611 fer are once again set to 0, and all entries in the depth buffer
612 are once again set to the maximum permitted depth value.
613
614 Optionally, one may provide an argument to only clear either the
615 image buffer or the depth buffer individually, while leaving the
616 other intact. With the image argument, only the image buffer is
617 cleared; with the depth argument, only the depth buffer is
618 cleared. Instead of full argument names, one may provide a mini‐
619 mum unique abbreviation, which has the same effect. The single
620 character z is also accepted as an alias for depth.
621
622 Like the print command, this command has no effect upon the cur‐
623 rent drawing state either.
624
625
626
627 reset maxval num_attribs [tupletype]
628
629 This updates the current maxval and number of attributes per
630 vertex (num_attribs), resetting the <u>image</u> buffer with a
631 new maxval and number of samples per tuple while at it. The pa‐
632 rameter maxval must be an integer in the closed range [1,
633 65535], and num_attribs must be an integer in the closed range
634 [1, 20].
635
636 Optionally, after the second argument, one may provide a string
637 to be assigned to the current tupletype. The string goes from
638 the first character after the second argument which is not white
639 space and continues until (and including) the last character be‐
640 fore the end of the line which is not white space. If a new tu‐
641 pletype is not provided, or the provided string is longer than
642 255 characters, the empty string is assigned to the current tu‐
643 pletype.
644
645 The side effects of running this command are
646
647
648
649 •
650
651 The new image buffer is completely cleared once the command is
652 executed.
653
654
655 •
656
657 All values in the current attribute values list are set to the
658 new maxval.
659
660
661 •
662
663 The current vertex list is reset.
664
665
666
667 However, it does not touch the depth buffer: it is left the same
668 way as it was found before the command. Also the drawing mode
669 remains the same (e. g. if pamtris was in FAN mode, it will con‐
670 tinue in that same mode, etc.).
671
672 If this command is given with an invalid value for maxval or
673 num_attribs, it is ignored and therefore none of the above side
674 effects apply, nor do the current maxval, num_attribs or tuple‐
675 type change at all.
676
677 It is permissible to give a value for maxval and num_attribs
678 equal to the current maxval and num_attribs, respectively, al‐
679 though the above side effects will still apply even in such
680 cases.
681
682 Since this command deals with memory allocation, it may fail to
683 execute successfully. If that happens, no lines of input will be
684 read anymore and pamtris will be terminated as if the quit com‐
685 mand was given.
686
687 quit
688
689 This terminates pamtris. It will not read any more lines of in‐
690 put after this command.
691
692
693
694
695
697 Texturing
698 It is possible to apply so-called "textures" to images produced with
699 pamtris by using a pair of vertex attributes as texture coordinates,
700 then using pamchannel(1) to select the appropriate channels in the out‐
701 put image(s), and finally processing the result through pamlookup(1),
702 providing the desired texture file as a "lookup table." If you are
703 drawing pictures in perspective, make sure to provide adequate values
704 for the w parameter to your vertex commands ( see above ⟨#cmd_vertex⟩ )
705 so that the resulting samples in the images produced by pamtris are
706 perspective-correct. You might want to consider using pnmtile(1) to
707 make textures which are inteded to be "repeated" along triangle meshes.
708
709 The animated GIF below is an example of what can be achieved using the
710 technique described above (Earth texture from nasa.gov
711 ⟨https://visibleearth.nasa.gov/view.php?id=73580⟩ ).
712
713 Rotating Earth
714
715
716 Anti-aliased edges
717 pamtris performs no anti-aliasing on triangle edges by itself. How‐
718 ever, it is possible to obtain anti-aliased images through a "super-
719 sampling" approach: draw your image(s) at a size larger than the de‐
720 sired final size, and then, when all postprocessing is done, downscale
721 the final image(s) to the desired size. Drawing images with twice the
722 desired width and height, then downscaling them to the intended size
723 while disregarding gamma (i.e. what pamscale -linear does) often pro‐
724 duces good enough results; but the larger the ratio "size of origi‐
725 nal image" / "size of downscaled image" , the better the quality of
726 the anti-aliasing effect.
727
728
730 pampick(1) pamchannel(1) pamstack(1) pamlookup(1) pamarith(1) pam‐
731 scale(1) pamdepth(1) pamexec(1) pam(1)
732
733
735 pamtris was new in Netpbm 10.84 (September 2018).
736
738 This manual page was generated by the Netpbm tool 'makeman' from HTML
739 source. The master documentation is at
740
741 http://netpbm.sourceforge.net/doc/pamtris.html
742
743netpbm documentation 15 April 2021 Pamtris User Manual(0)