|
|
1.1 ! root 1: .so ../ADM/mac ! 2: .XX 30 491 "The 10th Edition Raster Graphics System" ! 3: .fp 5 T CW \" T for Typewriter ! 4: .de TP \" An indented paragraph describing some command, tagged with the command name ! 5: .IP "\\fT\\$1\\fR" 8 ! 6: .if \\w'\\fT\\$1\\fR'-7n .br ! 7: .. ! 8: .de CI ! 9: .nr Sf \\n(.f ! 10: \%\&\\$3\f(CW\\$1\fI\&\\$2\f\\n(Sf ! 11: .. ! 12: .TL ! 13: The 10th Edition Raster Graphics System ! 14: .AU ! 15: Tom Duff ! 16: .AI ! 17: .MH ! 18: .AB ! 19: The current (late 1989) state of generating and displaying raster graphics ! 20: in Research ! 21: .UX ! 22: is described. ! 23: .AE ! 24: .2C ! 25: .NH ! 26: Introduction ! 27: .PP ! 28: The Research ! 29: .UX ! 30: system contains a number of commands to capture, manipulate, ! 31: display and record monochrome and full-color raster images. Three groups of ! 32: commands may be identified: ! 33: interactive programs that operate on a frame-buffer, ! 34: commands that operate on images stored in picture ! 35: files (see ! 36: .I picfile (5) ! 37: or |reference(picfile v10)), ! 38: and programs that interface to various graphical I/O devices: ! 39: video cameras, scanners, paper plotters, film cameras and video-tape ! 40: recorders. ! 41: .NH ! 42: Video Facilities ! 43: .PP ! 44: No discussion of our raster graphics software can ignore the ! 45: hardware on which it runs. The hardware available at different ! 46: sites will, of course, vary. For definiteness, and to provide ! 47: help for the local audience, this section will discuss the ! 48: hardware available in Center 1127's graphics and image processing ! 49: laboratory (MH 2C-524) and its neighborhood. Most other environments ! 50: will have hardware that is similar in spirit if different in detail. ! 51: .PP ! 52: There are seven work stations in 2C-528. On the day this was written, ! 53: five of them had TTY 5620 terminals, one had a Gnot terminal and ! 54: one had a SUN-3 workstation computer. Eventually, most of the 5620's ! 55: will be replaced with Gnots. Each work station also has ! 56: a Sony GDM-1901-12 video monitor that displays high-resolution ! 57: video signals. ! 58: .PP ! 59: The room contains other video displays and recorders, including ! 60: a Barco video projector in the ceiling, a 35-inch Mitsubishi monitor ! 61: at the front of the room, a 19-inch Barco monitor at work station 6, ! 62: two small Sony monitors in the video rack next to the audio console, ! 63: two Panasonic Super-VHS recorders, a Sony 3/4-inch (U-MATIC) video ! 64: player, a multi-standard (SECAM, NTSC, PAL) VHS player, a ! 65: Sony BVH-2500 1-inch (SMPTE-C) video tape recorder and a Sony video ! 66: camera. ! 67: .PP ! 68: The video equipment supports at least three incompatible video formats. ! 69: High-resolution ! 70: rgb video has 1024 scan lines, a 60 hz non-interlaced vertical scan rate, ! 71: and transmits red, green and blue information on separate cables with ! 72: synchronization pulses superimposed on the green channel. ! 73: Low-resolution rgb video has between 480 and 488 scan lines, 30hz ! 74: interlaced vertical scan, and separate rgb with sync on green. ! 75: NTSC (National Television Standards Committee) video has the same timing ! 76: characteristics as low-resolution rgb video, but encodes red, green, blue ! 77: and sync into a single signal. ! 78: NTSC is the encoding used by American, Canadian and Japanese television ! 79: broadcasters, and by almost all video recording and playback equipment ! 80: in those countries. ! 81: .PP ! 82: Various computer terminals generate video in other formats that our ! 83: equipment handles with only limited success. Gnots, 630s, ! 84: 5620s, Sun terminals, IBM-compatible PCs and Macintoshes all generate ! 85: mutually incompatible video. Their vertical and horizontal scan-rates ! 86: differ. The voltages and impedences of the signals they produce differ. ! 87: Their color encodings differ. Monitors that can display video from all ! 88: of these sources are rare, let alone hardware to convert from one format ! 89: to another. For example, the only reliable way to record a signal from ! 90: any of these sources is to place a camera in front of a monitor. The ! 91: quality of the resulting recordings is often bad. It is a black art ! 92: to adjust our Barco video projector to handle non-standard signals, ! 93: but with a few days notice it can often be done. Again, the results ! 94: are not often as good as one might like \(mi the projector does not ! 95: focus as tightly as a monitor and its brightness is limited. As better ! 96: video displays become available our situation will improve. ! 97: Table 1 summarizes the equipment available and the ! 98: video formats that each supports. ! 99: .1C ! 100: .KF ! 101: .TS ! 102: center box; ! 103: l| c| c| c| c| c| c. ! 104: Equipment High-res Low-res NTSC Gnot IBM PAL/SECAM ! 105: RGB RGB ! 106: = ! 107: workstation monitors \(bu ! 108: _ ! 109: Barco projector \(bu \(bu \(bu \(bu maybe maybe ! 110: _ ! 111: 35-inch Mitsubishi \(bu \(bu \(bu ! 112: _ ! 113: Barco at work station 6 \(bu \(bu ! 114: _ ! 115: Sony rack monitors \(bu ! 116: _ ! 117: Super-VHS recorders \(bu ! 118: _ ! 119: U-MATIC player \(bu ! 120: _ ! 121: 1-inch recorder \(bu ! 122: _ ! 123: multi-standard player \(bu ! 124: _ ! 125: camera \(bu \(bu ! 126: _ ! 127: Metheus frame buffers \(bu ! 128: _ ! 129: ITI frame buffer \(bu ! 130: _ ! 131: Pixel Machine \(bu \(bu ! 132: .TE ! 133: .sp .3 ! 134: .ce ! 135: \fBTable 1. \fRVideo devices ! 136: .SP .5 ! 137: .KE ! 138: .2C ! 139: .PP ! 140: We have several Metheus 3610 frame buffers (four on ! 141: .CW pipe , ! 142: one on ! 143: .CW arend , ! 144: one on ! 145: .CW encke ) ! 146: and an Imaging Technology, Inc. (ITI) RGB-512. All of our ! 147: frame buffers store 32 bits at each pixel, one byte each for red, green ! 148: blue and alpha. The 3610's generate high-resolution (1280\(mu1024) ! 149: video. The ITI generates low-resolution (512\(mu480) video that may ! 150: be recorded on video tape after conversion to NTSC. Connected to ! 151: .CW sol , ! 152: the Sun-3/160 at work station 1, is an AT&T Pixel Machine with ! 153: 58 processors. It can generate either high- or low-resolution video ! 154: under software control; the Pixel Machine documentation can tell you how. ! 155: .PP ! 156: Each piece of video equipment is connected to one of two ! 157: video switches. One switch handles high or low-resolution rgb video. ! 158: The other handles NTSC video exclusively. Under computer control, any ! 159: output port may be connected to any input port of the same switch. ! 160: The ! 161: .CW "vsw [-dcrvpi] [\fIiopair\fP ...] ! 162: command controls the video switches. ! 163: The switches' inputs and outputs are labelled by single characters ! 164: 0-9 and a-z. ! 165: An ! 166: .I iopair ! 167: is a pair of characters indicating an input and output to be connected ! 168: together. ! 169: The flags mean: ! 170: .TP -r ! 171: operate the rgb switch. ! 172: .TP -c ! 173: operate the composite (NTSC) switch. ! 174: .TP -d ! 175: print a description of the switch's inputs and outputs ! 176: .TP -p ! 177: print a list of iopairs indicating the state of the switch. ! 178: .TP -i ! 179: initialize the switch to an unknown state. ! 180: .TP -v ! 181: with ! 182: .CW -p ! 183: or ! 184: .CW -d , ! 185: make the descriptions more verbose. ! 186: .LP ! 187: The video switch is ! 188: .I not ! 189: straightforward to use. ! 190: It is easy to be confused about what the inputs and outputs are; ! 191: always remember that these are from the switch's point of view. ! 192: Thus, the input marked ! 193: .CW "pixel machine" ! 194: is the Pixel Machine's output. ! 195: The connections to the video switch have a history of ad hoc undocumented ! 196: changes. ! 197: .PP ! 198: The Sony BVH-2500 video recorder produces very high ! 199: quality recordings on 1" video tape. Since it can overwrite ! 200: arbitrary single frames of the tape, it is an ideal machine ! 201: on which to record animation. ! 202: .PP ! 203: Before using a new tape, ! 204: you must record (``grind'') time-code on it, numbering ! 205: each frame of the tape. ! 206: Time-code values are usually denoted by values ! 207: of the form ! 208: .I hh.mm.ss.ff ! 209: (like ! 210: .CW 02.43.17.15 ). ! 211: The 2500's monitor output, called ! 212: .CW 2500.mon ! 213: by ! 214: .I vsw , ! 215: displays time-code superimposed on the 2500's ! 216: output signal. ! 217: .PP ! 218: To grind time-code, use ! 219: .I vsw ! 220: to connect the color bar generator ! 221: (\fIvsw\fP calls this ! 222: .CW cbars ) ! 223: to the 2500's input, thread up a tape, and manually set the ! 224: 2500 to record by pushing its ! 225: .I record ! 226: and ! 227: .I play ! 228: buttons simultaneously. Let it go until the tape runs out. ! 229: .PP ! 230: The ! 231: .I 2500 ! 232: command operates the recorder, reading instructions ! 233: from its standard input. Its instruction set is ! 234: moderately complicated; for most uses the following ! 235: subset is adequate: ! 236: .TP "cue \fIhh.mm.ss.ff ! 237: Cue the tape to the given time code. The ! 238: time-code displayed on the 2500's monitor ! 239: output may be a few frames off, ! 240: but the recorder will be cued to the correct point. ! 241: .TP "still mode on ! 242: Put the recorder in single-frame record mode. ! 243: .TP "still mode off\fP ! 244: Put the recorder out of single-frame record mode. ! 245: .TP "snap [\fIn\fT] ! 246: Record ! 247: .I n ! 248: frames (default 1) at the current cue point, and ! 249: advance the cue point by ! 250: .I n ! 251: frames. The recorder must be in single frame mode. ! 252: .TP "play ! 253: Start playing back from the current cue point. ! 254: .TP "stop ! 255: Stop the recorder. ! 256: .TP "!\fIunix-command ! 257: Run the given ! 258: .I unix-command ! 259: using ! 260: .CW /bin/sh . ! 261: .PP ! 262: We currently have only two sources of digital video that ! 263: may be recorded on video tape. These are the Pixel Machine ! 264: and the ITI frame buffer attached to kwee. To use either ! 265: one, you must use ! 266: .CW "vsw -r ! 267: to patch its output to the NTSC color encoder, ! 268: and ! 269: .CW "vsw -c ! 270: to patch the endcoder's output to the video recorder. ! 271: The ITI frame buffer is also useful as a frame-grabber, ! 272: capturing its video input in its memory whence it may ! 273: be saved in a picture file or otherwise manipulated. ! 274: .PP ! 275: The ITI is served by an ancient software regime whose ! 276: commands all begin with the letters ! 277: .CW iti . ! 278: .TP "itifbinit -x ! 279: Re-initialize the ITI to the state expected by the ! 280: rest of the software. The ITI is often unused for ! 281: days at at time, during which its health often ! 282: decays. ! 283: .CW itifbinit ! 284: is its restorative. The ! 285: .CW -x ! 286: flag causes its input and output to be synchronized. ! 287: This is always a good idea. ! 288: .TP itigamma ! 289: Load the ITI's color map to correct intensities ! 290: for display on CRT monitors. ! 291: .TP "itigrab -[gs] ! 292: Run the frame-grabber. The ! 293: .CW -g ! 294: flag starts the frame-grabber running. ! 295: The displayed image will track the ITI's input ! 296: video. ! 297: .CW -s ! 298: stops the frame-grabber, freezing the image. ! 299: Unadorned by flags, ! 300: .CW grab ! 301: starts the frame-grabber and stops it one frame ! 302: later. ! 303: .TP "itigit \fIpicture-file ! 304: Copy the image stored in ! 305: .I picture-file ! 306: into the ITI. ! 307: .TP "itisiv \fIpicture-file ! 308: Save the image in the ITI in ! 309: .I picture-file . ! 310: .PP ! 311: Paragraphs needed describing imagitek scanner, henry's document ! 312: scanners, matrix qcr, postscript. ! 313: .NH ! 314: Frame-buffer commands ! 315: .PP ! 316: A frame buffer is a large memory organized as a two-dimensional array of ! 317: pixels. Our Metheus 3610 frame buffers have 1024 scan lines of 1280 pixels ! 318: each. The ITI frame buffer has 480 lines of 512 pixels. The coordinate ! 319: system has (0,0) in the upper left-hand corner, with x increasing to ! 320: the right, and y increasing down. This apparent weirdness is fairly standard, ! 321: since it makes video output happen in row-major order. ! 322: .PP ! 323: Here we will mostly discuss commands for the Metheus displays. The corresponding ! 324: ITI commands have the same names, but prefixed with the string ! 325: .CW iti . ! 326: .PP ! 327: There are several Metheus frame buffers attached to pipe, named ! 328: .CW /dev/om[0-7] . ! 329: All of the commands discussed below determine which one to use ! 330: by examining the environment variable ! 331: .CW FB . ! 332: It is often hard to tell what frame buffer is displayed on which monitor ! 333: because of the video switch. The ! 334: .CW fbi ! 335: (frame buffer identification) command displays each frame buffer's name in it. ! 336: .PP ! 337: Our frame buffers all have 32 bits per pixel, divided into ! 338: four 8-bit channels. The channel values are normally thought of ! 339: as fractions ranging from 0 to 1, although frame buffer commands perversely ! 340: refer to them as integers between 0 and 255. ! 341: Three of the channels specify the red, green and ! 342: blue color components of the image. The fourth channel, called ! 343: .I alpha , ! 344: is used to indicate whether or not the image covers the pixel, and is not ! 345: normally displayed. ! 346: .I Alpha ! 347: is used to control image compositing operations|reference(porter duff compositing digital images). ! 348: Fractional values of ! 349: .I alpha ! 350: describe pixels that the image partly or translucently covers, and ! 351: facilitate anti-aliased compositing. ! 352: .PP ! 353: Each frame buffer contains three 256 entry look-up tables that specify ! 354: mappings from the values stored in the red, green and blue channels ! 355: to the voltages supplied at the frame buffers' video outputs. ! 356: The ! 357: .CW "gamma [\fIpower\fP] ! 358: command loads these tables are loaded with a function that ! 359: inverts the power-law relation between voltage and luminous flux ! 360: normally encountered in CRT displays. Thus, pixel values normally ! 361: correspond directly to displayed intensities. ! 362: .I Power ! 363: is the exponent of the power-law. The default of 2.3 is adequate ! 364: for all our displays. ! 365: .PP ! 366: Other patterns may be loaded into the color map by ! 367: .CW "getmap \fIfile\fP [...] ! 368: command, whose arguments are a list of files containing color maps. ! 369: On the ITI, the argument `\fT%\fP' refers ! 370: to the current content of the frame buffer's color map. (The Metheuses' ! 371: color maps are write-only.) The functional composition of the specified ! 372: color maps is loaded into the frame buffer's color map. ! 373: .CW Getmap ! 374: searches for files in the current directory and in ! 375: .CW /fb/cmap ! 376: and ! 377: .CW /usr/td/cmap/lib . ! 378: A color map file contains 256 records of 3 bytes each, specifying the output ! 379: values for the corresponding red, green and blue input values. ! 380: The ! 381: .CW ranmap ! 382: command loads random values into the color map. ! 383: .PP ! 384: Our frame buffers have the ability to magnify a part of the image, via the ! 385: .CW "zoom [\fIamount\fP [\fIx y\fP]] ! 386: command. ! 387: With three arguments, ! 388: .CW zoom ! 389: magnifies by ! 390: .I amount , ! 391: mapping the point ! 392: .I "(x, y) ! 393: (default (0,0)) to the upper left-hand corner of the screen. ! 394: With no arguments, ! 395: .I Amount ! 396: defaults to 1. ! 397: The Metheuses can magnify by any integral factor from 1 to 16. ! 398: The ITI can magnify only by 1 or 2. ! 399: .PP ! 400: An array of images can be viewed in sequence by zooming and panning ! 401: using the ! 402: .CW "movie \fIxsize ysize nx ny\fP [\fIdelay\fP] ! 403: command. The arguments are the size of the individual ! 404: frames, the number of frames in the array in each ! 405: direction, and optionally the number of 60ths of a second ! 406: to delay between frames. The frames must be arranged ! 407: boustrophedonically, with alternate rows proceding from ! 408: left to right and right to left. (This is because neither ! 409: Metheus nor ITI frame buffers can pan in x and y simultaneously ! 410: without glitching.) ! 411: .PP ! 412: There are a number of commands to load simple patterns into the frame buffer: ! 413: .TP "clr [-w \fIx0 y0 x1 y1\fT] [\fIr\fT [\fIg b\fT [\fIalpha\fT]]] ! 414: sets all pixels to the given value. If only ! 415: .I r ! 416: is given, ! 417: .I g ! 418: and ! 419: .I b ! 420: are set to ! 421: .I r . ! 422: If ! 423: .I alpha ! 424: is not given, it is set to 255 (completely opaque.) ! 425: The ! 426: .CW -w ! 427: flag restricts attention to pixels inside the window whose upper-left corner is ! 428: .I (x0,y0) ! 429: and with ! 430: .I (x1,y1) ! 431: just diagonally outside the lower-right corner. ! 432: .TP cbars ! 433: displays a color-bars test pattern. The 8 bars at the top exercise all combinations ! 434: of the 3 primary colors. The 9 patches at the bottom are a logarithmic ! 435: (perceptually uniform) grey scale. ! 436: .TP "ramp [-w \fIx0 y0 x1 y1\fT] [-v] [[\fIcol0\fT] \fIcol1\fT] ! 437: displays a horizontal ramp whose color is ! 438: .I col0 ! 439: at the left ! 440: and ! 441: .I col1 ! 442: at the right. ! 443: Colors are specified as for ! 444: .CW clr ! 445: (green and blue default equal to red, alpha defaults to 255). ! 446: If ! 447: .I col0 ! 448: defaults to ! 449: .CW "0 0 0 255" . ! 450: .CW -w ! 451: restricts ! 452: .CW clr ! 453: to the given window. ! 454: .CW -v ! 455: gives a vertical ramp with ! 456: .I col0 ! 457: at the top ! 458: and ! 459: .I col1 ! 460: at the bottom. ! 461: .TP "colors [-gfr] ! 462: displays a 16 by 16 array of grey-colored (equal red, green and blue) squares in ! 463: the middle of the screen with red, green and blue ramps at the top. This is ! 464: mostly useful for examining color maps. The flags modify the display in small ways. ! 465: .CW -r ! 466: suppresses the ramps. ! 467: .CW -g ! 468: suppresses the gaps between the squares. ! 469: .CW -f ! 470: expands the display to fill the full screen, making the patches non-square and ! 471: suppressing the ramps. ! 472: .PP ! 473: The ! 474: .CW xhair ! 475: command can be used to examine the contents of the frame buffer. ! 476: It is named after the cross-hair that it draws on the screen. Single ! 477: character commands manipulate the cross-hair, magnify the video and ! 478: print pixel values. The commands are ! 479: .nf ! 480: .ta 8n ! 481: \fTh\fP print the help message ! 482: \fTlrud\fP move left, right, up or down 1 pixel ! 483: \fTLRUD\fP move left, right, up or down 16 pixels ! 484: \fT0\fP move to center of screen (x=256, y=240) ! 485: \fT1-8\fP magnify \(mu1\-8 ! 486: \fT9\fP magnify \(mu16 ! 487: \fTp\fP print current coordinates and pixel value ! 488: \fTP\fP print pixel after each command (toggle) ! 489: \fTm\fP type coordinates to move to ! 490: \fTx\fP type x coordinate to move to ! 491: \fTy\fP type y coordinate to move to ! 492: \fTc\fP change the crosshair display to a rectangle ! 493: \fTs\fP manipulate other corner of rectangle ! 494: \fT^D,q\fP exit xhair and run command ! 495: \fTQ\fP exit xhair, don't demagnify or run command ! 496: \fTX\fP exit and don't run command ! 497: .PP ! 498: If ! 499: .CW xhair ! 500: is given arguments, they represent a command to be executed before exiting, ! 501: after making substitutions for any argument whose first character is ! 502: .CW % . ! 503: The substitutions made are: ! 504: .ta 8n ! 505: .nf ! 506: \fT%r\fP the current rectangle ! 507: \fT%w\fP the current rectangle ! 508: \fT%p\fP the upper-left corner of the rectangle ! 509: \fT%o\fP the upper-left corner of the rectangle ! 510: \fT%c\fP the lower-right corner of the rectangle ! 511: \fT%x\fP the x coordinate of the upper-left corner ! 512: \fT%y\fP the y coordinate of the upper-left corner ! 513: \fT%X\fP the x coordinate of the lower-right corner ! 514: \fT%Y\fP the y coordinate of the lower-right corner ! 515: .NH ! 516: Picture file commands ! 517: .PP ! 518: Most of our raster graphics commands require no special hardware. They synthesize ! 519: images in picture files from textual or other discriptions, they modify images ! 520: in picture files, producting results in picture files, or they combine the contents ! 521: of several picture files to produce composite images, again storing the result in ! 522: a picture file. ! 523: .PP ! 524: The simplest picture file command is ! 525: .CW pcp , ! 526: which takes two picture file names and copies the first onto the second. ! 527: Names whose first character is ! 528: .CW % ! 529: are interpreted specially: ! 530: .ta 8n ! 531: .nf ! 532: \fT%in\fP read from standard input ! 533: \fT%out\fP write standard output ! 534: \fT%0\fP Metheus frame buffer #0. ! 535: \&... ! 536: \fT%7\fP Metheus frame buffer #7. ! 537: \fT%iti\fP ITI frame buffer. ! 538: .fi ! 539: .PP ! 540: .CW Pcp ! 541: has a number of options that alter the copied picture: ! 542: .TP "-o\ \fIx y ! 543: Add ! 544: .I "(x,y) ! 545: to the picture's window coordinates. ! 546: .TP "-w \fIx0\ y0\ x1\ y1 ! 547: Clip the input picture's window to the given coordinates. ! 548: If ! 549: .CW -o ! 550: and ! 551: .CW -w ! 552: are both given, the window is clipped before being offset. ! 553: .TP "-t\ \fItype ! 554: The output picture will have ! 555: .CW "TYPE= \fItype" . ! 556: .TP "-c\ \fIchannels ! 557: The output picture will have ! 558: .CW "CHAN=\fIchannels" . ! 559: .I Channels ! 560: must be one of ! 561: .CW m , ! 562: .CW ma , ! 563: .CW rgb , ! 564: .CW rgba , ! 565: .CW mz... , ! 566: .CW maz... , ! 567: .CW rgbz... , ! 568: or ! 569: .CW rgbaz... . ! 570: Likewise, the input picture must ! 571: have ! 572: .CW CHAN= ! 573: set to one of these possibilities. ! 574: If the input has no ! 575: .CW a ! 576: channel, 255 is used. ! 577: If it has no ! 578: .CW z... ! 579: channels, floating point 0. is used. ! 580: Color images are converted to monochrome using the standard ! 581: NTSC luminance (\fTa=.30r+.59g+.11b\fP). ! 582: Monochrome images are converted to color by \fTr\fP=\fTg\fP=\fTb\fP=\fTm\fP. ! 583: .PP ! 584: The ! 585: .CW lam ! 586: command combines any number of images, writing a picture file whose window ! 587: is large enough to contain all the windows of its inputs. The input files ! 588: are combined with pixels of later images overwriting earlier ones. As ! 589: this is only really useful if the windows of the input images differ, ! 590: each input name may be preceded by ! 591: .CI -w "x0 y0 x1 y1 ! 592: and ! 593: .CI -o " x y ! 594: options to clip and offset it. ! 595: Options ! 596: .CI -W " x0 y0 x1 y1 ! 597: and ! 598: .CI -O " x y ! 599: clip and offset the output image. ! 600: Option ! 601: .CI -o " file ! 602: specifies the output file name (standard output by default), ! 603: and ! 604: .CI -c " channels ! 605: specifies the output ! 606: .CW CHAN= . ! 607: .PP ! 608: The ! 609: .CW posit ! 610: and ! 611: .CW 3matte ! 612: commands combine images using the two- and three-dimensional compositing ! 613: operations described in |reference(porter duff compositing digital images) ! 614: and |reference(duff composite3d). ! 615: Each takes a list of picture file names as arguments, producing a composite ! 616: on standard output. The ! 617: .CW -a ! 618: option will cause either program to output only the ! 619: .CW rgb ! 620: channels, suppressing ! 621: .CW a ! 622: (and ! 623: .CW z... ! 624: in the case of ! 625: .CW 3matte ). ! 626: .PP ! 627: There is an army of commands to read an image and, under the control of a few ! 628: parameters, write a modified image. These include: ! 629: .TP "bwquantize \fIin out ! 630: File ! 631: .I in ! 632: contains a color image or a monochrome image with a colormap. ! 633: A gray-level image is written in ! 634: .I out , ! 635: using the NTSC luminance formula. ! 636: .TP "clip \fIleft right in out ! 637: Clip an image horizontally to the limits ! 638: .I left ! 639: and ! 640: .I right . ! 641: A picture that does not fill out the limits is filled with black pixels. ! 642: .TP "xpand [-s] \fIin out [lo hi [inlo inhi]] ! 643: The input picture has its dynamic range adjusted so that pixels in the ! 644: range ! 645: .I inlo ! 646: to ! 647: inhi ! 648: are mapped to the range ! 649: .I lo ! 650: to ! 651: .I hi ! 652: (default 0 to 255). ! 653: The default values for ! 654: .I inlo ! 655: and ! 656: .I inhi ! 657: are determined per channel by examining the input picture. ! 658: The ! 659: .CW -s ! 660: option causes all channels to be examined together. ! 661: .I Lo , ! 662: .I hi , ! 663: .I inlo ! 664: and ! 665: .I inhi ! 666: may have any values whatsoever. If ! 667: .I hi ! 668: is smaller than ! 669: .I lo , ! 670: pixel values will be inverted, producing a negative image. ! 671: Any output pixel that would be mapped outside the range ! 672: 0\-255 is set to 0 or 255. ! 673: .TP "dither \fIin out ! 674: Convert a full-color (3 channel) picture to one channel with a color-map ! 675: by dithering. ! 676: .TP "floyd \fIin out ! 677: Convert an 8-bit gray-scale picture to one bit per pixel using a version of the Floyd-Steinberg ! 678: error-diffusion method. ! 679: .TP "halftone \fIscreen in out ! 680: Convert an 8-bit gray-scale picture to one bit using a given half-tone ! 681: .I screen . ! 682: The available screens are ! 683: .KS ! 684: .in 2n ! 685: .TS ! 686: lFCW l. ! 687: ALLEBACH Allebach's ordered-dither ! 688: BAYER Standard ordered-dither ! 689: BLUENOISE A pebble-screen pattern ! 690: CLASSIC A 3-pixel-wide dot screen ! 691: CLASSIC2 Another 3-pixel-wide dot screen ! 692: CLASSIC3 A 4-pixel-wide dot screen ! 693: CLASSIC4 An 8-pixel-wide dot screen ! 694: DIAMOND Rao and Arce's ordered-dither ! 695: LINE Ulichney's line screen ! 696: RING A concentric ring screen ! 697: TILT18 A tilted dot screen ! 698: .TE ! 699: .KE ! 700: .TP "he \fIin out ! 701: Histogram equalization: the intensity histogram ! 702: of the input image is measured. The output image ! 703: has its contrast altered for maximum use of the ! 704: output range, equalizing the histogram ! 705: as much as possible. ! 706: .TP "hysteresis \fIlow high in out ! 707: Pixel values of the input picture below ! 708: .I low ! 709: are mapped to zero. ! 710: Those above ! 711: .I high ! 712: are mapped to 255. ! 713: If ! 714: .I low ! 715: and ! 716: .I high ! 717: are not equal, any region ! 718: below ! 719: .I high ! 720: that has any 8-connected neighbors below ! 721: .I low ! 722: is mapped to zero. ! 723: .TP "picaverage \fIweight in1 in2 out ! 724: The output picture is a weighted average of the two ! 725: input pictures. ! 726: .I Weight ! 727: determines the fraction of the average contributed by ! 728: .I in1 . ! 729: .TP "piccat \fTin1 ... out ! 730: The input pictures are concatenated one atop another. The ! 731: output has the width of the widest input. ! 732: .TP "picjoin \fTin1 ... out ! 733: The input pictures are concatenated side by side. The ! 734: output has the height of the highest input. ! 735: .TP "adapt \fIin out ! 736: Adaptive histogram equalization: each pixel of the output image ! 737: is the histogram-equalized value of the center of a 7\(mu7 pixel ! 738: window surrouding it in the input image. ! 739: .TP "ahe \fIin out ! 740: 17\(mu17 adaptive histogram equalization. There should be an option to ! 741: .CW adapt ! 742: setting the window size. ! 743: .TP "clean \fIin out ! 744: Bayer-Powell noise removal filter. If the center pixel of each 3\(mu3 ! 745: window in the input differs from the average of the other 8 pixels by ! 746: more than 64, it is replaced by the periphery-average. This has the ! 747: effect of flattening isolated noise pixels. ! 748: .TP "crispen \fIin out ! 749: 3\(mu3 linear crispening filter. Convolves the input image with ! 750: the kernel ! 751: .P1 ! 752: -1 -1 -1 ! 753: -1 9 -1 ! 754: -1 -1 -1 ! 755: .P2 ! 756: This is a mild high-pass filter. ! 757: .TP "edge \fIin out ! 758: 3\(mu3 linear edge-detection filter. ! 759: Convolves the input image with ! 760: the kernel ! 761: .P1 ! 762: -1 -1 -1 ! 763: -1 8 -1 ! 764: -1 -1 -1 ! 765: .P2 ! 766: This is just the difference between the original image and the output of ! 767: .CW crispen . ! 768: .TP "edge2 \fIin out ! 769: 3\(mu3 non-linear edge-detection (Sobel operator) filter. ! 770: .TP "extremum \fIin out ! 771: 3\(mu3 extremum filter. Replaces the center pixel of each ! 772: by the value in the 3\(mu3 window surrounding it that most ! 773: differs from it. ! 774: .TP "laplace \fIin out ! 775: 3\(mu3 "Laplacian filter. ! 776: Convolves the input image with ! 777: the kernel ! 778: .P1 ! 779: 0 -1 0 ! 780: -1 5 -1 ! 781: 0 -1 0 ! 782: .P2 ! 783: This is a fairly extreme high-pass filter. ! 784: .TP "median \fIin out ! 785: 3\(mu3 median filter. Each pixel is replaced by the ! 786: median of the 3\(mu3 window surrounding it. ! 787: .TP "smooth \fIin out ! 788: 3\(mu3 Bartlett filter. ! 789: Convolves the input image with ! 790: the kernel ! 791: .P1 ! 792: 1/16 2/16 1/16 ! 793: 2/16 4/16 2/16 ! 794: 1/16 2/16 1/16 ! 795: .P2 ! 796: This is a moderately strong low-pass filter. ! 797: .TP "picreflect \fIin out ! 798: Reflect the input picture about its vertical center line. ! 799: .TP "quantize \fIin out ! 800: Convert a full-color picture to an 8-bit picture with colormap. ! 801: This does a much better job than ! 802: .CW dither . ! 803: It tries to pick an colormap that optimally clusters the input's ! 804: colors. ! 805: .TP "resample \fInpix in out ! 806: Resample the input image to be ! 807: .I npix ! 808: pixels wide. The filter used in resampling minimizes both ! 809: pre- and post-aliasing. ! 810: .TP "transpose \fIinput output ! 811: Transpose the input picture. This is useful in conjunction with ! 812: commands that operate on scan-lines, like ! 813: .CW resample ! 814: or ! 815: .CW clip , ! 816: to perform operations on columns instead of rows. ! 817: .TP "shear \fIin out angle ! 818: Rotate the input image by the given ! 819: .I angle ! 820: (in degrees). It's called ! 821: .I shear ! 822: because it operates by shearing the image 3 times ! 823: (horizontally, then vertically, then horizontally). ! 824: It fails for angles of 180\(de. ! 825: .TP "lx [-o\fIfile\fT] [-A\fIaspect\fT] [-a] [-s\fIscale\fT] [-r\fIrot\fT] [-x\fIxscale\fT] [-y\fIyscale\fT] \fIin\fT ! 826: Perform a linear transformation on the input image. ! 827: The ! 828: .CW -o ! 829: option specifies the output file name. The default is standard output. ! 830: The ! 831: .CW -A ! 832: option specifies the aspect ratio of the pixels. The default is 1. ! 833: The ITI frame-grabber produces images whose pixel aspect-ratio is 1.25. ! 834: The ! 835: .CW -a ! 836: option suppresses the writing of an alpha channel. Normally ! 837: an alpha channel is computed even for input images that don't have one, ! 838: since the output picture is often rotated and thus doesn't completely ! 839: cover its window. ! 840: .IP ! 841: The transformation is specified by a sequence of options. The specified ! 842: transformations are combined in the order given to yield a composite transformation. ! 843: The relevant options are: ! 844: .nf ! 845: .ta 8n ! 846: \fT-s\fIscale\fR scale by \fIscale\fR. ! 847: \fT-r\fIrot\fR rotate by \fIrot\fR degrees clockwise. ! 848: \fT-x\fIxscale\fR scale in x by \fIxscale\fR. ! 849: \fT-y\fIyscale\fR scale in y by \fIyscale\fR. ! 850: .PP ! 851: There are several commands to generate images from ! 852: three-dimensional geometric descriptions of various sorts. ! 853: Most of these produce ! 854: .CW CHAN=rgbaz... ! 855: images that may be combined using ! 856: .CW 3matte . ! 857: In their output files, points at the near clipping plane will be mapped to ! 858: points having ! 859: .I z=0 , ! 860: and points at the far clipping plane will have ! 861: .I z=1 . ! 862: .TP "ncpr [-a \fIaspect\fT] [-w \fIx0 y0 x1 y1\fT] [-c \fIrgbaz\fT] \fIinput\fT [\fIoutput\fT] ! 863: New Cheezy Polygon Renderer. ! 864: .I Output ! 865: (default standard output) is the name of the picture file that will contain the rendered ! 866: version of the scene described in ! 867: .I input , ! 868: a text file specifying a polygonal scene. ! 869: The ! 870: .CW -a ! 871: option sets the pixel aspect-ratio (default 1.) ! 872: The ! 873: .CW -w ! 874: option sets the window of the output picture. ! 875: The ! 876: .CW -c ! 877: option specifies which channels should be written to the output picture. ! 878: .IP ! 879: The input file contains a sequence of single-letter commands, each with several ! 880: numeric parameters. The commands are: ! 881: .IP ! 882: \fTv \fIfov near far ex ey ez lx ly lz ux uy uz\fR ! 883: .br ! 884: Set viewing parameters. ! 885: .I Fov ! 886: is the angle subtended vertically by the screen at the eye point. ! 887: Points whose distance from the eye is not between ! 888: .I near ! 889: and ! 890: .I far ! 891: will be clipped away before drawing. However tempted, do not set ! 892: .I near ! 893: to zero, lest underflow or divide-check occur. ! 894: .I "(ex, ey, ez) ! 895: is the coordinate of the eye, the point from which the scene is viewed ! 896: and the center of perspective. ! 897: .I "(lx, ly, lz) ! 898: is a vector pointing from the eye toward the center of the scene. ! 899: The point ! 900: .I "(lx+ex, ly+ey, lz+ez) ! 901: is mapped into the center of the screen. ! 902: .I "(ux, uy, uz) ! 903: is the up vector, the direction of the zenith. The point ! 904: .I "(lx+ux, ly+uy, lz+uz) ! 905: is mapped into a point somewhere above the center of the screen. ! 906: .IP ! 907: \fTl \fIx y z\fR ! 908: .br ! 909: Set the direction of the light source to ! 910: .I "(x, y, z) . ! 911: The light source is ``at infinity'' in the given direction. ! 912: .IP ! 913: \fTb \fIred green blue alpha\fR ! 914: Clear the screen to the given color. ! 915: .I Red , ! 916: .I green , ! 917: .I blue ! 918: and ! 919: .I alpha ! 920: should all be between 0 and 255. ! 921: .IP ! 922: \fTc \fIindex red green blue alpha\fR ! 923: Set a color table entry. Indices into the color table are used ! 924: to specify the colors of polygons (see below.) ! 925: The table has 500 entries. Unless reloaded by the ! 926: .CW c ! 927: command, the first 256 entries contain the 256 shades of gray, ! 928: the following 12 entries (256-267) are set to 12 logarithmically ! 929: spaced (perceptually equal) gray shades, and the next 20 entries ! 930: (268-287) to 20 logarithmically spaced gray shades. ! 931: .IP ! 932: \fTt \fIx0 y0 z0 x1 y1 z1 x2 y2 z2 c0 c1\fR ! 933: .br ! 934: Render a triangle with vertices ! 935: .I "(x0, y0, z0)" , ! 936: .I "(x1, y1, z1) ! 937: and ! 938: .I "(x2, y2, z2)" . ! 939: On one side its color is ! 940: .I c0 , ! 941: on the other it is ! 942: .I c1 . ! 943: If ! 944: .I c0 ! 945: or ! 946: .I c1 ! 947: is positive, the polygon's color is found in the corresponding color ! 948: table entry. If negative, the color is found by modifying the color ! 949: table entry as though the surface were illuminated by a light source ! 950: whose direction was specified by the ! 951: .CW l ! 952: command. ! 953: .IP ! 954: \fTp \fIc0 c1 x0 y0 z0 x1 y1 z1 ... xn yn zn \fT;\fR ! 955: .br ! 956: Render a polygon whose color is ! 957: .I c0 ! 958: on one side and ! 959: .I c1 ! 960: on the other. ! 961: The polygon's vertices are ! 962: .I "(x0, y0, z0)" , ! 963: .I "(x1, y1, z1)" ,..., ! 964: .I "(xn, yn, zn)" . ! 965: .in -8n ! 966: .TP "quad [-a] [-z] [-w \fIx0 y0 x1 y1\fP] \fIin out ! 967: .br ! 968: Compute an image of a quadric surface. The ! 969: .CW -a ! 970: option suppresses writing out the alpha channel. ! 971: The ! 972: .CW -z ! 973: option suppresses writing out the z channel. ! 974: The ! 975: .CW -w ! 976: option specifies the output window. ! 977: The input file should contain 34 floating point numbers. ! 978: The first ten numbers are the upper triangle of the symmetric ! 979: matrix describing the quadratic form (in screen coordinates.) ! 980: The next 16 numbers are a matrix that converts screen-space ! 981: coordinates into world-space normals for illumination computations. ! 982: The next three numbers are the direction of the light source. ! 983: The next four numbers are the red, green, blue and alpha of the ! 984: surface's color. The last number is the amount of ambient light ! 985: in the environment. ! 986: .TP "terrain \fIin out ex ey ez lx ly fov near far ! 987: Render a terrain image. ! 988: The input file ! 989: is a 2-channel picture file containing 16-bit elevation data on a regular grid. ! 990: .I "(ex, ey, ez) ! 991: is the eye position. ! 992: .I "(lx, ly, 0) ! 993: is a vector pointing from the eye to the center of the scene. ! 994: The up direction is ! 995: .I "(0,0,1)" . ! 996: .I Fov ! 997: is the vertical field-of-view angle. ! 998: .I Near ! 999: and ! 1000: .I far ! 1001: are the distances from the eye to the near and far clipping planes. ! 1002: .TP "bg \fIr0 g0 b0 r1 g1 b1 out ! 1003: Generate a background card whose color varies smoothly ! 1004: from ! 1005: .I "(r0, g0, b0) ! 1006: at the top to ! 1007: .I "(r1, g1, b1) ! 1008: at the top. ! 1009: Its z coordinate is set to 2, which is beyond the far clipping plane. ! 1010: .NH ! 1011: Animation ! 1012: .PP ! 1013: To use a command-based raster graphics system as described here to ! 1014: for animation requires writing command files to create and record ! 1015: long sequences of images. Typical command files contain long sequences ! 1016: of repeated commands with slowly changing numeric parameters. Several ! 1017: sequences starting and ending at different times may be interleaved ! 1018: to describe overlapping motion. They are at best tedious and at worst ! 1019: tricky to generate by hand or using the usual tools. ! 1020: .PP ! 1021: .I Moto ! 1022: is a command generator tailored for an animator's needs. Its input is ! 1023: a concise description of the animation to be performed; its output is ! 1024: a command file suitable for input to ! 1025: .I sh , ! 1026: .I rc ! 1027: or some other command interpreter. ! 1028: Its arguments are an optional file name containing a ! 1029: .I moto ! 1030: program (default standard input) and list of numeric parameters ! 1031: that are made available to the program. ! 1032: .PP ! 1033: A ! 1034: .I moto ! 1035: program consists of a list of groups of commands. Each block is ! 1036: guarded by a range of frames. Here is an example: ! 1037: .P1 ! 1038: 1,5: pcp this %0 ! 1039: pcp %0 that ! 1040: .P2 ! 1041: This generates ! 1042: .P1 ! 1043: pcp this %0 ! 1044: pcp %0 that ! 1045: pcp this %0 ! 1046: pcp %0 that ! 1047: pcp this %0 ! 1048: pcp %0 that ! 1049: pcp this %0 ! 1050: pcp %0 that ! 1051: pcp this %0 ! 1052: pcp %0 that ! 1053: .P2 ! 1054: The command group is repeated for each of frames 1 to 5. ! 1055: .PP ! 1056: Groups may contain parameter ranges enclosed in brackets ! 1057: .CW [] : ! 1058: .P1 ! 1059: 1,5: pcp frame.[1,5] %0 ! 1060: echo snap|2500 ! 1061: .P2 ! 1062: This generates: ! 1063: .P1 ! 1064: pcp frame.1 %0 ! 1065: echo snap|2500 ! 1066: pcp frame.2 %0 ! 1067: echo snap|2500 ! 1068: pcp frame.3 %0 ! 1069: echo snap|2500 ! 1070: pcp frame.4 %0 ! 1071: echo snap|2500 ! 1072: pcp frame.5 %0 ! 1073: echo snap|2500 ! 1074: .P2 ! 1075: .PP ! 1076: Programs may have multiple groups, each guarded by ! 1077: a separate range of frames. For each frame, ! 1078: .I moto ! 1079: checks each group and processes those ! 1080: whose guards include the current frame number. ! 1081: .PP ! 1082: Two special guards, ! 1083: .CW BEGIN ! 1084: and ! 1085: .CW END , ! 1086: specify actions to be taken before an after processing frames: ! 1087: .P1 ! 1088: BEGIN: clr ! 1089: 1,5: pcp section[1,5] %0 ! 1090: END: pcp %0 composite ! 1091: .P2 ! 1092: This generates ! 1093: .P1 ! 1094: clr ! 1095: pcp section1 %0 ! 1096: pcp section2 %0 ! 1097: pcp section3 %0 ! 1098: pcp section4 %0 ! 1099: pcp section5 %0 ! 1100: pcp %0 composite ! 1101: .P2 ! 1102: .LP ! 1103: .I Moto ! 1104: allows complex computations inside parameter brackets: ! 1105: .P1 0 ! 1106: 1,10: clr [127.5*(1-cos([0,360]))] ! 1107: .P2 ! 1108: This generates ! 1109: .P1 ! 1110: clr 0 ! 1111: clr 29.82933350233 ! 1112: clr 105.35985734747 ! 1113: clr 191.25 ! 1114: clr 247.3108091502 ! 1115: clr 247.3108091502 ! 1116: clr 191.25 ! 1117: clr 105.35985734747 ! 1118: clr 29.82933350233 ! 1119: clr 0 ! 1120: .P2 ! 1121: .PP ! 1122: Expressions may include constants and variables. ! 1123: All values are double-precision floating point numbers. ! 1124: The operators ! 1125: .CW = , ! 1126: .CW / , ! 1127: .CW + , ! 1128: .CW - ! 1129: (both unary and binary), ! 1130: .CW < , ! 1131: .CW > , ! 1132: .CW <= , ! 1133: .CW >= , ! 1134: .CW == , ! 1135: .CW != , ! 1136: .CW "? :" ! 1137: and ! 1138: .CW ! , ! 1139: all with their meanings as in C, except that all results ! 1140: are coerced to ! 1141: .CW double . ! 1142: The result of ! 1143: .CW a%b ! 1144: is ! 1145: .CW a-b*(int)(a/b) . ! 1146: The result of ! 1147: .CW "a && b ! 1148: is ! 1149: .CW "a?b:a . ! 1150: The result of ! 1151: .CW "a || b ! 1152: is ! 1153: .CW "a?a:b . ! 1154: The exponentiation operator is ! 1155: .CW ^ , ! 1156: also written ! 1157: .CW ** . ! 1158: The expression ! 1159: .CW [a,b] ! 1160: variesfrom ! 1161: .CW a ! 1162: to ! 1163: .CW b , ! 1164: linearly as the frame number varies between the guards of the ! 1165: group containing the expression. ! 1166: The expression ! 1167: .CW a[b,c] ! 1168: has the value ! 1169: .CW a*b+(1-a)*c . ! 1170: Its value varies from ! 1171: .CW b ! 1172: to ! 1173: .CW c ! 1174: as ! 1175: .CW a ! 1176: varies from 0 to 1. ! 1177: The expression ! 1178: .CW $i ! 1179: has the value of the ! 1180: .CW i 'th ! 1181: parameter following the file name on ! 1182: .I moto 's ! 1183: command line. ! 1184: .PP ! 1185: The precedence of operators is, from lowest to highest: ! 1186: .P1 ! 1187: = ! 1188: ? : ! 1189: || ! 1190: && ! 1191: < <= == != > >= ! 1192: + - ! 1193: * / % ! 1194: [ ] ! 1195: ^ ** ! 1196: - \fR(unary)\fP ! $ ! 1197: .P2 ! 1198: Expressions may be parenthesized to alter precedence. ! 1199: .PP ! 1200: The following math functions are available: ! 1201: .QS ! 1202: .ft CW ! 1203: fabs floor ceil sqrt hypot sin cos tan ! 1204: asin acos atan exp log log10 sinh cosh tanh ! 1205: gamma besj0 besj1 besjn besy0 besy1 besyn ! 1206: .ft R ! 1207: .QE ! 1208: All math functions are as described in the C library, ! 1209: except that angles are measured in degrees rather than ! 1210: radians for the trig and inverse trig functions. ! 1211: In addition ! 1212: .CW hypot ! 1213: may have two or three arguments, ! 1214: .CW atan ! 1215: may take two arguments instead of one, ! 1216: and may also be spelled ! 1217: .CW atan2 . ! 1218: .PP ! 1219: For parameterization, and to allow even more complex ! 1220: computations, ! 1221: .I moto ! 1222: has variables, assignment and computation groups. ! 1223: A computation group is distinguished from a command group ! 1224: by having a double colon separating its guard from the ! 1225: expressions to be computed: ! 1226: .P1 0 ! 1227: BEGIN:: n=5 ! 1228: 1,n:: x=512*sin([0,90]) ! 1229: 1,n: pcp -w 0 0 [x] 488 pic.[1,n] %0 ! 1230: .P2 ! 1231: This generates ! 1232: .P1 0 ! 1233: pcp -w 0 0 0 488 pic.1 %0 ! 1234: pcp -w 0 0 195.93391737093 488 pic.2 %0 ! 1235: pcp -w 0 0 362.03867196751 488 pic.3 %0 ! 1236: pcp -w 0 0 473.02632064578 488 pic.4 %0 ! 1237: pcp -w 0 0 512 488 pic.5 %0 ! 1238: .P2 ! 1239: .PP ! 1240: Upon occasion it is useful to split ! 1241: .I moto 's ! 1242: output into several files, under program control. ! 1243: A group that is separated from its guards by an at-sign ! 1244: .CW @ ! 1245: instead of a colon names a file into which ! 1246: subsequent output is to be written. For example, ! 1247: .P1 ! 1248: 1,5@ file.[1,5] ! 1249: 1,5: This is file.[1,5]. ! 1250: .P2 ! 1251: creates 5 files, with names ! 1252: \fTfile.1\fR,...,\fTfile.5\fR. ! 1253: Each file's contents will announce its name. ! 1254: .PP ! 1255: As is true for all sufficiently large programs, ! 1256: .I moto ! 1257: has a shell escape. A group separated from its ! 1258: guards by an exclamation point ! 1259: .CW ! ! 1260: instead of a colon has its result text interpreted ! 1261: by a subshell. ! 1262: .PP ! 1263: Finally, Figure 1 shows an example taken from a real application. ! 1264: This ! 1265: .I moto ! 1266: program composites the frames of a short movie showing ! 1267: two flying saucers, flying in formation, chased by a third, ! 1268: racing over New Jersey. The flying ! 1269: saucer images (files ! 1270: .CW run.* ! 1271: and ! 1272: .CW chase.* ) ! 1273: and the background (file ! 1274: .CW bg ) ! 1275: have been computed in advance. In the composite, the ! 1276: .CW run.* ! 1277: images are re-used, staggered in time, to do the ! 1278: first two saucers. ! 1279: .1C ! 1280: .KF ! 1281: .P1 ! 1282: BEGIN:: nchase=108 ! 1283: nrun=195 ! 1284: d1=12 ! 1285: d2=32 ! 1286: end=nrun+d2 ! 1287: chase=end-nchase+1 ! 1288: 1,end: inputs= # empty the input list ! 1289: 1,nrun: inputs="$inputs run.[1,nrun]" # add the first saucer to the input list ! 1290: 1+d1,nrun+d1: ! 1291: inp="$inputs run.[1,nrun]" # add the second saucer ! 1292: chase,end: ! 1293: inp="$inputs chase.[1,nchase]" # add the chasing saucer ! 1294: 1,end: ! 1295: 3matte -a $inp bg frame.[1,end] # create the composite ! 1296: .P2 ! 1297: .ce ! 1298: \fBFigure 1.\fP Flying saucer script ! 1299: .KE ! 1300: .2C ! 1301: .NH ! 1302: References ! 1303: .PP ! 1304: |reference_placement
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.