Annotation of researchv10dc/vol2/pico/pico.ms, revision 1.1.1.1

1.1       root        1: .so ../ADM/mac
                      2: .XX pico 423 "Pico \(em A Language For Composing Digital Images"
                      3: .nr dP 2
                      4: .nr dV 3p
                      5: .EQ
                      6: delim @#
                      7: .EN
                      8: .ND July, 1989
                      9: .TL
                     10: Pico \(em A Language For Composing Digital Images
                     11: .AU "MH 2C-521" 6335
                     12: Gerard J. Holzmann
                     13: .AI
                     14: .MH
                     15: .AB
                     16: \fIPico\fP is a small expression language for picture compositions.
                     17: It can be used either interactively with a display or stand alone as a
                     18: picture file editor.
                     19: The following \fIpico\fP script, for instance, turns an arbitrary digitized
                     20: image stored in a file 
                     21: .CW in 
                     22: upside down, rotates it by 90 degrees,
                     23: and writes its negative into a file 
                     24: .CW out :
                     25: .P1 20n
                     26: $ pico
                     27: 1: new = Z-$in[X-y,x]
                     28: 2: w out
                     29: 3: q
                     30: $
                     31: .P2
                     32: .PP
                     33: Numerous examples of
                     34: .I pico
                     35: transformations of pictures are included throughout this volume.
                     36: .AE
                     37: .2C
                     38: .NH
                     39: Black&White Images
                     40: .PP
                     41: The pictures that can be manipulated by \fIpico\fP are stored as
                     42: regular files in the picture file format described in
                     43: .I picfile (5).
                     44: The picture editor is most conveniently used interactively
                     45: with a Metheus frame buffer display.
                     46: The result of picture transformations is then directly visible
                     47: and can be used to correct or enhance the mistakes that one is
                     48: bound to make.
                     49: .SH
                     50: New and Old
                     51: .PP
                     52: Assuming that you want to work interactively and have access to one
                     53: of the Metheus frame buffers, e.g. on 
                     54: .CW pipe ,
                     55: a session with \fIpico\fP can be started by typing
                     56: .P1 0
                     57: $ pico -m\fIN\fP
                     58: b&w, 512x512 pel, Metheus display
                     59: 1: 
                     60: .P2
                     61: where
                     62: .I N
                     63: is the device number of the frame buffer to be used.
                     64: By default,
                     65: .I N
                     66: is zero and opens
                     67: .CW /dev/om0 .
                     68: Also by default the size of the workarea is 512x512 pixels.
                     69: If you need to work with larger images, you
                     70: can override the default by explicitly setting a different
                     71: window width and height, for instance:
                     72: .P1 0
                     73: $ pico -m5 -w1024 -h1024
                     74: b&w, 1024x1024 pel, Metheus display
                     75: 1: 
                     76: .P2
                     77: The maximum size image that the Metheus frame buffer
                     78: can display is 1280x1024 pixels.
                     79: .PP
                     80: The number followed by a colon in the example above
                     81: is \fIpico\fP's prompt for commands.
                     82: .PP
                     83: The result of the last edit operation (initially an all black image)
                     84: is accessible under the predefined name 
                     85: .CW old ,
                     86: and
                     87: the destination of the image transformations is known as 
                     88: .CW new .
                     89: To quickly get a picture into the workbuffer, you can use the command 
                     90: .CW get
                     91: followed by the name of the file with the image.
                     92: .P1 0
                     93: 1: get "pjw"
                     94: .P2
                     95: The most frequently used command in \fIpico\fP is 
                     96: .CW x ,
                     97: short for 
                     98: .CW execute .
                     99: To make a black&white negative from the current picture
                    100: the command would be:
                    101: .P1 0
                    102: 2: x new=Z-old
                    103: .P2
                    104: where Z is a predefined constant with the value of maximum white (255).
                    105: By default the transformation is applied to every pixel on the screen.
                    106: .PP
                    107: Assume we have two image files with portraits.
                    108: We can open these files by using 
                    109: .CW get ,
                    110: or we can specify them
                    111: on the \fIpico\fP command line, as follows, using
                    112: .CW /dev/om5 :
                    113: .P1 0
                    114: $ pico -m5 ./face/rob ./face/pjw
                    115: b&w, 512x512 pel, Metheus display
                    116: 1: 
                    117: .P2
                    118: We can create a new image, for instance, by averaging the two faces:
                    119: .P1 0
                    120: $ pico -m5 ./face/rob ./face/pjw
                    121: b&w, 512x512 pel, Metheus display
                    122: 1: x new=($rob+$pjw)/2
                    123: 2: 
                    124: .P2
                    125: The transformation is written as an assignment of an
                    126: expression to the destination 
                    127: .CW new .
                    128: Names preceded by a dollar sign refer to picture files,
                    129: for instance as specified on the command line.
                    130: A long name such as 
                    131: .CW ./face/rob 
                    132: can be abbreviated
                    133: to its base name 
                    134: .CW rob 
                    135: (the part following the last slash).
                    136: Not all file names have to be provided on the command line though.
                    137: We can also 
                    138: .CW append 
                    139: a new file 
                    140: .CW doug ,
                    141: without reading it, by typing:
                    142: .P1 0
                    143: 2: a "doug"
                    144: .P2
                    145: The double quotes are necessary.
                    146: They avoid confusion when, for instance, 
                    147: .CW / 
                    148: symbols
                    149: are part of the filename.
                    150: We can check which files are currently open by typing 
                    151: .CW f :
                    152: .P1 0
                    153: 3: f
                    154: $0: old        color   resident
                    155: $1: rob  b&w resident
                    156: $2: pjw  b&w resident
                    157: $3: doug b&w absent
                    158: .P2
                    159: The numbers in the first column serve as a shorthand for the file names.
                    160: Typing 
                    161: .CW $1 
                    162: therefore is equivalent to typing 
                    163: .CW $rob .
                    164: We will use both notations 
                    165: .CW $1 
                    166: and 
                    167: .CW $rob 
                    168: below.
                    169: The first line 
                    170: .CW $0 
                    171: is a shorthand for 
                    172: .CW old 
                    173: and refers to
                    174: the workarea (the screen in interactive usage).
                    175: .PP
                    176: We have a black and white image on the screen that is an average
                    177: of the two files 
                    178: .CW rob 
                    179: and 
                    180: .CW pjw .
                    181: To see 
                    182: .CW rob 
                    183: separately we could type:
                    184: .P1 0
                    185: 4: x new=$1
                    186: .P2
                    187: but that is hardly an inspiring procedure.
                    188: Let's just take the left half
                    189: or rob's face combined with the right half of peter's:
                    190: .P1 0
                    191: 5: x new=(x<256)?$rob:$pjw
                    192: .P2
                    193: or to make a mirror image:
                    194: .P1 0
                    195: 5: x new=(x<256)?$rob[x,y]:$rob[X-x,y]
                    196: .P2
                    197: The variable 
                    198: .CW x 
                    199: used in the expression is predefined.
                    200: Don't confuse it with the first 
                    201: .CW x 
                    202: on the command line
                    203: which identifies the type of command to
                    204: be executed.
                    205: The variable 
                    206: .CW x 
                    207: gives the current x-coordinate of a pixel
                    208: during transformations.
                    209: Since in this case 512 pixels fit on one scan line, a pixel in
                    210: the middle of the screen has an 
                    211: .CW x -coordinate
                    212: of 256.
                    213: The maximum value of 
                    214: .CW x 
                    215: is given by a predefined variable 
                    216: .CW X .
                    217: .CW X/2 ,
                    218: therefore, is a safer way to specify the middle of a scan line.
                    219: .PP
                    220: The expression above is a conditional of the form:
                    221: .P1 0
                    222: \fIcondition\fP ? \fIiftrue\fP : \fIiffalse\fP
                    223: .P2
                    224: For every screen position where the condition holds the 
                    225: .I iftrue 
                    226: part
                    227: of the expression applies and everywhere else the 
                    228: .I iffalse 
                    229: part applies.
                    230: Another predefined variable of this type is 
                    231: .CW y
                    232: (the y-coordinate of the destination).
                    233: The maximum 
                    234: .CW y 
                    235: value is called 
                    236: .CW Y .
                    237: Since
                    238: .CW $0
                    239: refers to the screen we can turn the picture
                    240: on the screen upside down by typing:
                    241: .P1 0
                    242: 6: x new = $0[x, Y-y]
                    243: .P2
                    244: All pixels in the black&white picture are internally represented by a
                    245: value in the range 0..255, where 0 means black and 255 means white.
                    246: To reverse an image, therefore it would suffice to subtract the current
                    247: value of each pixel from its maximum value 255, which is stored in constant 
                    248: .CW Z .
                    249: Getting very bold we can turn the picture on its side,
                    250: and make it negative by saying:
                    251: .P1 0
                    252: 8: x new = 255 - old[y,511-x]
                    253: .P2
                    254: or, slightly more abstract
                    255: .P1 0
                    256: 9: x new = Z - old[y,Y-x]
                    257: .P2
                    258: Note that we swapped x and y to turn the picture on its side.
                    259: Nothing can stop us now:
                    260: .P1 0
                    261: 10: x new=(x<X/3)?$1:(x>X*2/3)?$2: \*(cr
                    262:        3*((x-X/3)*$2+(X*2/3-x)*$1)/X
                    263: .P2
                    264: fades 
                    265: .CW rob 
                    266: slowly into 
                    267: .CW pjw .
                    268: (We have used \*(cr to break the line into
                    269: two pieces for lay-out purposes.
                    270: When using \fIpico\fP, it should be typed as one complete line.)
                    271: Actually this last transformation is easier to read as a little \fIpico\fP
                    272: program.
                    273: To see how this works, and what the defaults in the above expression
                    274: are, the above expression could be typed as:
                    275: .P1 0
                    276: 10: x {
                    277:        int L, R
                    278: 
                    279:        L = X/3; R = X*2/3
                    280: 
                    281:        for (y = 0; y < Y; y++)
                    282:        for (x = 0; x < X; x++)
                    283:        {       if (x < L)
                    284:                        new[x,y] = $1
                    285:                else if (x > R)
                    286:                        new[x,y] = $2
                    287:                else
                    288:                        new[x,y] = 3*((x-L)* \*(cr
                    289:                                $2+(R-x)*$1)/X
                    290:        }
                    291: }
                    292: .P2
                    293: There fewer defaults here, though an assignment to 
                    294: .CW new 
                    295: is still
                    296: interpreted as a parallel assignment to all three color channels in the
                    297: picture.
                    298: You can override also these defaults by making the program still more explicit,
                    299: for instance by using the suffixes 
                    300: .CW red , 
                    301: .CW grn ,
                    302: and 
                    303: .CW blu 
                    304: to access
                    305: color channels separately: 
                    306: .CW new[x,y].red , 
                    307: .CW new[x,y].grn ,
                    308: and 
                    309: .CW new[x,y].blu .
                    310: To see the effect you need to set the workbuffer to color mode first
                    311: with the command 
                    312: .CW color .
                    313: (You go back to the default black&white mode with the command 
                    314: .CW nocolor ).
                    315: .PP
                    316: All normal arithmetic operators from C are available.
                    317: The 
                    318: .CW ^
                    319: operator, for instance, makes an 
                    320: .I "exclusive or"
                    321: of its operands.
                    322: Thus,
                    323: .P1 0
                    324: 11: x new=x^y^$rob
                    325: .P2
                    326: is a particularly striking effect, and
                    327: .P1 0
                    328: 13: x new = $rob +(Z - $rob[x+2, y+2])
                    329: .P2
                    330: is an attempt to make a relief.
                    331: .PP
                    332: There is no range checking on explicit or implicit array indexing.
                    333: The use of 
                    334: .CW x+2 
                    335: in the last expression is therefore risky
                    336: and is best protected with a conditional:
                    337: .P1 0
                    338: 13: x new=$rob+(Z-(x<509 && y<509)? \*(cr
                    339:                $rob[x+2,y+2]:Z)
                    340: .P2
                    341: or more conveniently with the builtins 
                    342: .CW xclamp
                    343: and 
                    344: .CW yclamp :
                    345: .P1 0
                    346: 14: x new=$rob+(Z-$rob[xclamp(x+2), \*(cr
                    347:                yclamp(y+2)])
                    348: .P2
                    349: Another promising attempt to make a core dump would be to type
                    350: something like
                    351: .P1 0
                    352: 14: x new=$rob[x*y, x/y]
                    353: .P2
                    354: .NH
                    355: Color Images
                    356: .PP
                    357: A complete picture specifies pixel values for each of three
                    358: separate color channels: red, green, and blue.
                    359: When the editor is used in black&white mode only the
                    360: red channel is used.
                    361: When a black&white picture is converted to color mode,
                    362: all three channels are made equal.
                    363: The omission of a channel suffix to 
                    364: .CW old , 
                    365: .CW new 
                    366: or a file name
                    367: is similarly interpreted to mean that a transformation expression will
                    368: apply equally to all three color channels.
                    369: By specifying an explicit suffix
                    370: .CW red , 
                    371: .CW grn ,
                    372: or 
                    373: .CW blu ,
                    374: however, we can write each channel separately.
                    375: So:
                    376: .P1 0
                    377: 14: color
                    378: 15: x new.red=$rob
                    379: 16: x new.grn=$rob
                    380: 17: x new.blu=255-$rob
                    381: .P2
                    382: will write 
                    383: .CW rob 
                    384: on the red and green channels, and its negative on the
                    385: blue channel.
                    386: If 
                    387: .CW rob 
                    388: is a black&white picture then typing
                    389: .CW $rob
                    390: is, of course,
                    391: equivalent to typing
                    392: .CW $rob.red .
                    393: We could also have combined the first two lines in a chain assignment:
                    394: .P1 0
                    395: 18: x new.red=new.grn=$rob
                    396: .P2
                    397: We can also write a separate value to each channel
                    398: by using 
                    399: .CW composites .
                    400: A color composite is written as a comma separated list
                    401: of three values, enclosed in square brackets:
                    402: .P1 0
                    403: 19: x new.rgb=[$rob,$rob,Z-$rob ]
                    404: .P2
                    405: The channels are addressed by the three fields of the composite in
                    406: the order: [red, green, blue].
                    407: Omitting to specify a composite when an 
                    408: .CW rgb 
                    409: destination is
                    410: used typically results in only the red channel being written.
                    411: As expected,
                    412: .P1 0
                    413: 20: x new.rgb=[old.grn,old.blu,old.red ]
                    414: .P2
                    415: rotates the colors of the picture.
                    416: And, of course, you can freely combine
                    417: the color suffixes with array indexing:
                    418: .CW $rob.blu
                    419: is just a shorthand
                    420: for 
                    421: .CW "$rob[x, y].blu "
                    422: where the variables 
                    423: .CW x ,
                    424: and 
                    425: .CW y 
                    426: can be replaced by just any monstrous C-style expression.
                    427: .NH
                    428: The Color Maps
                    429: .PP
                    430: When working interactively,
                    431: the color map in the Metheus frame buffer display
                    432: can be set with one of the commands
                    433: .CW cmap
                    434: (all channels),
                    435: .CW cmap.red ,
                    436: .CW cmap.grn , or
                    437: .CW cmap.blu .
                    438: The color map is a mapping table that can arbitrarily map
                    439: pixel brightness values in the range 0..255 to other
                    440: brightness values, within the same range 0..255.
                    441: The update, however, only happens on the screen and is not stored
                    442: when the image file is written.
                    443: The variable 
                    444: .CW i 
                    445: is used to index the color map.
                    446: For instance:
                    447: .P1 0
                    448: 21: x cmap = Z-i
                    449: .P2
                    450: will very quickly make a negative, and
                    451: .P1 0
                    452: 22: x cmap = i
                    453: .P2
                    454: turns the picture back to normal.
                    455: To fake color in a black and white image you can try:
                    456: .P1 0
                    457: 23: x cmap.red = (i<=85)?i:0
                    458: 24: x cmap.grn = (i>85 && i<170)?i:0
                    459: 25: x cmap.blu = (i>=170)?i:0
                    460: .P2
                    461: Remember that changing the color map only changes the appearance
                    462: of the picture on the screen, not its definition in memory.
                    463: .NH
                    464: Read, Write, and Windows
                    465: .PP
                    466: The 
                    467: .CW append
                    468: command, to add files to the list of dollar arguments
                    469: was discussed before.
                    470: Using the command 
                    471: .CW get 
                    472: instead of 
                    473: .CW a 
                    474: will also put the file into $0,
                    475: that is on the screen.
                    476: To save the current state of the display in a file, use:
                    477: .P1 0
                    478: 26: w filename
                    479: .P2
                    480: A raw black&white picture file, without the picture file header,
                    481: can be written by using 
                    482: .CW "w -" 
                    483: instead of 
                    484: .CW w
                    485: (for instance when dumping a file to be processed
                    486: by software uneducated in picture file headers).
                    487: The size of the file written conforms to the
                    488: current window size of the editor (see also below).
                    489: To close a no longer used file and free up some memory for others, say:
                    490: .P1 0
                    491: 27: d doug
                    492: .P2
                    493: or
                    494: .P1 0
                    495: 27: d $1
                    496: .P2
                    497: giving the file's base name or its dollar number.
                    498: To restrict the updates to a window on the screen you can set:
                    499: .P1 0
                    500: 30: window 10 100 200 300
                    501: .P2
                    502: which makes a window with origin at (x,y) = (10,100), 200 pixels wide
                    503: and 300 pixels deep.
                    504: And, if you really want to exit \fIpico\fP you can type a control-D
                    505: or resort to the 
                    506: .CW quit
                    507: command:
                    508: .P1 0
                    509: 32: q
                    510: .P2
                    511: .NH
                    512: Programs
                    513: .PP
                    514: As shown in one of the examples above, it is possible to write
                    515: small \fIpico\fP programs for the more difficult transformations
                    516: that cannot be handled by the defaults.
                    517: The control structure for the \fIpico\fP programs is again stolen from C.
                    518: .PP
                    519: A \fIpico\fP program starts with a left curly brace 
                    520: .CW { 
                    521: followed by
                    522: zero or more declarations of (long) integers or arrays.
                    523: For instance,
                    524: .P1 0
                    525: 33: x {
                    526:        int a, b; array ken[100]
                    527: 
                    528:        ...
                    529: .P2
                    530: Note carefully that the left curly brace turns off the default control
                    531: flow over all the pixels in a picture; the control flow in a program
                    532: must be specified explicitly.
                    533: The above program fragment declares two local integers 
                    534: .CW a 
                    535: and 
                    536: .CW b 
                    537: which
                    538: by default will be initialized to zero,
                    539: and an array of 100 (long) integers named 
                    540: .CW ken ,
                    541: also initialized to zeros.
                    542: To initialize it to another value, use constants:
                    543: .P1 0
                    544: int a = 9
                    545: .P2
                    546: Statements can either be separated by newlines or by explicit semicolons.
                    547: Here then is a list of valid types of statements:
                    548: .P1 0
                    549: \fIlvalue\fP = \fIexpr\fP
                    550: if (\fIexpr\fP) \fIstmnt\fP
                    551: if (\fIexpr\fP) \fIstmnt\fP else \fIstmnt\fP
                    552: for (\fIexpr\fP; \fIexpr\fP; \fIexpr\fP) \fIstmnt\fP
                    553: while (\fIexpr\fP) \fIstmnt\fP
                    554: do \fIstmnt\fP while (\fIexpr\fP)
                    555: \fIlabel\fP: \fIstmnt\fP
                    556: goto label
                    557: { \fIstmnt\fP }
                    558: .P2
                    559: An \fIlvalue\fP is an explicitly declared local variable or array element,
                    560: one of the predefined variables 
                    561: .CW x ,
                    562: or 
                    563: .CW y ,
                    564: or a picture
                    565: element.
                    566: A picture element can again be a file name such as
                    567: .CW $doug
                    568: with a
                    569: default selection of the pixel inside it,
                    570: .CW $doug[x,y] ,
                    571: or it can be
                    572: more elaborate as in
                    573: .CW "$doug[x/2, y<<1].red" .
                    574: The destination of the transformation, is again referred to by
                    575: the keyword 
                    576: .CW new , 
                    577: but this time it needs an explicit array indexing.
                    578: The equivalent of
                    579: .P1 0
                    580: 34: x new=old[y,x]
                    581: .P2
                    582: to turn the picture on its side, can be written as a \fIpico\fP program:
                    583: .P1 0
                    584: 35: x {
                    585:        for (y = 0; y < 512; y++)
                    586:        for (x = 0; x < 512; x++)
                    587:                new[x,y] = old[y,x]
                    588: }
                    589: .P2
                    590: Note that also the control flow must be explicit.
                    591: Typing only
                    592: .P1 0
                    593: 36: x { new[x,y] = old[y,x] }
                    594: .P2
                    595: would use the initial (zero) values of 
                    596: .CW x 
                    597: and 
                    598: .CW y 
                    599: and
                    600: merely assign
                    601: .CW "new[0,0] = old[0,0]" .
                    602: .NH
                    603: Array Indexing and Control Flow Defaults
                    604: .PP
                    605: One more word about defaults.
                    606: \fIPico\fP tries to be smart about assigning types to values.
                    607: When a single rvalue is needed and a color composite is available
                    608: and average of the color channels is the default, for instance:
                    609: .P1 0
                    610: .CW old becomes
                    611: .CW (old[x,y].red+old[x,y].grn+old[x,y].blu)/3 .
                    612: .P2
                    613: If on the other hand a value is available and a composite is
                    614: needed the value will be replicated into a fake composite.
                    615: To override the defaults assignments can of course always
                    616: be made more explicit.
                    617: Normal cases should work as expected, for instance, by default:
                    618: .P1 0
                    619: new = old
                    620: .P2
                    621: truly means
                    622: .P1 0
                    623: new.red=old.red;
                    624: new.grn=old.grn;
                    625: new.blu=old.blu
                    626: .P2
                    627: .NH
                    628: Procedures
                    629: .PP
                    630: There is a facility in \fIpico\fP to declare named segments of code and
                    631: use these as functions or procedures.
                    632: As an example, the following command declares a procedure 
                    633: .CW doit
                    634: that makes a histogram of a window of pixels on the screen.
                    635: It is equivalent to the sequence:
                    636: .P1 0
                    637: 37: window a b w d
                    638: 38: x { global array histog[256]; }
                    639: 39: x histo[old]++
                    640: 40: window 0 0 512 512
                    641: .P2
                    642: In a procedure this is written as:
                    643: .P1 0
                    644: 37: def doit(a, b, w, d) {
                    645:        global array histog[256]
                    646: 
                    647:        for (y = a; y < a+w; y++)
                    648:        for (x = b; x < b+d; x++)
                    649:                histog[old[x,y]]++
                    650: }
                    651: .P2
                    652: The declaration prefix 
                    653: .CW global 
                    654: extends the scope of an array so that it can be
                    655: referred to in subsequent procedures, programs or expressions.
                    656: We can now call the procedure and use the histogram to arbitrarily
                    657: change the color map:
                    658: .P1 0
                    659: 38: x { doit(0,0,512,512); }
                    660: 39: x cmap = histog[i]%256
                    661: .P2
                    662: Or more usefully, to calculate and apply a simple
                    663: histogram equalization:
                    664: .P1 0
                    665: 40: x {
                    666:        int ave, i, j, R, L, Hint;
                    667:        global array eqlz[256]
                    668: 
                    669: .P3
                    670:        for (i = ave = 0; i < 256; i++)
                    671:                ave += histog[i];
                    672:        ave /= 256
                    673: 
                    674: .P3
                    675:        for (i = R = Hint = 0; i < 256; i++)
                    676:        {       L = R
                    677:                Hint += histog[i]
                    678:                while (Hint > ave)
                    679:                {       Hint -= ave
                    680:                        R++
                    681:                }
                    682:                j = (L+R)/2
                    683:                eqlz[i] = (j>255)?255:j
                    684:        }
                    685: }
                    686: 41: x new=eqlz[old]
                    687: .P2
                    688: When \fIpico\fP starts up it reads a small set of library procedures
                    689: by simulating an 
                    690: .CW r 
                    691: command (see Table 1).
                    692: These definitions are stored in the file
                    693: .CW  /usr/lib/pico/defines .
                    694: The builtins listed in Table 2 can be used in \fIpico\fP programs and
                    695: \fIpico\fP procedures.
                    696: .NH
                    697: Non-Interactive Use of \fIPico\fP
                    698: .PP
                    699: When \fIpico\fP is used without having access to a frame buffer
                    700: all commands will still work.
                    701: To check the result of executing commands
                    702: it can be convenient to write what would have been the current screen image
                    703: into a file with the 
                    704: .CW w 
                    705: command
                    706: and view it in another \fImux\fP-window on the 5620 (or 630) terminal with
                    707: a command like 
                    708: .I flicks .
                    709: For instance, in one window the session can be:
                    710: .P1 0
                    711: $ pico rob pjw
                    712: 1: nocolor
                    713: 2: x new=($rob*$pjw)/255
                    714: 3: w - junk
                    715: 4: 
                    716: .P2
                    717: While in another window the file is displayed
                    718: with 
                    719: .I flicks , 
                    720: as follows:
                    721: .P1 0
                    722: $ flicks -em junk
                    723: .P2
                    724: .NH
                    725: See Also
                    726: .PP
                    727: More examples on how to use \fIpico\fP, and on its internal structure,
                    728: can be found in:
                    729: |reference(pico %no_cite)|reference(digital darkroom %no_cite)
                    730: .PP
                    731: |reference_placement
                    732: .FC
                    733: .1C
                    734: .TS
                    735: center;
                    736: c c
                    737: lFCW lw(4i).
                    738: _
                    739: COMMAND                        DESCRIPTION
                    740: =
                    741: a [x y w d] file       T{
                    742: append file with optional offset/dimensions
                    743: T}
                    744: d basename/$n  delete file
                    745: h file T{
                    746: read header information from file(s)
                    747: T}
                    748: r file read (library) command file
                    749: w [-] file     T{
                    750: write file or window with or without a header
                    751: format: default = \fIpico\fP header, \- means no header
                    752: T}
                    753: _
                    754: nocolor        T{
                    755: update & display only 1 channel
                    756: T}
                    757: color  T{
                    758: update & display all 3 channels
                    759: T}
                    760: _
                    761: window x y w d T{
                    762: restrict workarea to this window
                    763: T}
                    764: _
                    765: get [x y w d] file     T{
                    766: read file contents into 
                    767: .CW old
                    768: T}
                    769: get $n T{
                    770: refresh 
                    771: .CW old 
                    772: with an already opened file
                    773: T}
                    774: _
                    775: f      show mounted files
                    776: show [name]    T{
                    777: show symbol information (values)
                    778: T}
                    779: functions      show functions
                    780: _
                    781: def name { pprog }     define a function
                    782: x expr execute expr in default loop
                    783: x { pprog }    execute \fIpico\fP program
                    784: _
                    785: q      quit
                    786: _
                    787: .TE
                    788: .ce
                    789: File names containing nonalphanumeric characters (period, slash) must be enclosed in double quotes.
                    790: .sp .5
                    791: .ce
                    792: \fBTable 1.\fR Command Summary
                    793: .SP 3
                    794: .TS
                    795: center;
                    796: lFCW lw(4i).
                    797: _
                    798: printf(string, args)   recognizes only: \f(CW%d\fP, \f(CW%s\fP, \f(CW\en\fP, \f(CW\et\fP
                    799: x_cart(radius, angle)  T{
                    800: convert radius and angle (degrees: 0..360) into x_coordinate
                    801: T}
                    802: y_cart(radius, angle)  T{
                    803: convert radius and angle (degrees: 0..360) into y_coordinate
                    804: T}
                    805: X_cart(r,a),Y_cart(r,a)        T{
                    806: same as [\fIxy\fP]_\fIcart\fP, but expects \fIangle\fP in centidegrees
                    807: T}
                    808: r_polar(x,y)   convert \fIx,y\fP coordinate into radius
                    809: a_polar(x,y)   T{
                    810: angle returned is in degrees: 0..360, acuuracy=\(+- 2 degrees
                    811: T}
                    812: A_polar(x,y)   angle returned is in centidegrees: 0..36000
                    813: putframe(nr)   dump window into the file \f(CW"frame.%6d"\fP, \fInr\fP
                    814: getframe(nr)   T{
                    815: read from the file \f(CW"frame.%6d"\fP, \fInr\fP
                    816: T}
                    817: setcmap(i, r,g,b)      write \fIi\fPth value in colormap
                    818: getcmap(i, r,g,b)      read \fIi\fPth value in colormap
                    819: redcmap(i, z)
                    820: grncmap(), blucmap()
                    821: _
                    822: sin(angle), cos(angle) T{
                    823: returns 0..10,000, \fIangle\fP in degrees : 0..360
                    824: T}
                    825: Sin(angle), Cos(angle) T{
                    826: same but expects \fIangle\fP in centidegrees: 0..36000
                    827: T}
                    828: atan(x, y)     T{
                    829: arc-tangent of \fIy/x\fP, returns angle in degrees: 0..360
                    830: T}
                    831: exp(a) as advertised
                    832: log(a),log10(a)        returns 1024*result
                    833: sqrt(a)        integer square root of \fIa\fP
                    834: pow(a,b)       \fIa\fP to the power \fIb\fP
                    835: rand() returns a random integer \fIr\fP: 0\(<=\fIr\fP<32768.
                    836: _
                    837: .TE
                    838: .ce
                    839: \fBTable 2.\fR Builtin Procedures

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.